{
  "id": 4253811,
  "title": "Learning Elixir: Project Structure",
  "url": "https://urgent.news/2026/08/29/learning-elixir-project-structure",
  "topic": "tech",
  "section": "Tech",
  "published": "2026-08-29T18:45:20.000Z",
  "source": {
    "name": "Dev.to",
    "slug": "dev-to",
    "url": "https://dev.to/abreujp/learning-elixir-project-structure-832"
  },
  "original_language": "en",
  "account": "When an Elixir project grows beyond a handful of modules, pasting definitions into the interactive Elixir shell (IEx) becomes unmanageable. Redefinition warnings accumulate, name collisions arise, and everything vanishes when the session ends. A real solution is to create a project structure that maps the modules onto the file system, defining where each module resides, how file names correspond to module names, and which sections other developers may enter. This article will build a complete Mix project from scratch, demonstrating the evolution from a simple `mix new` command to the addition of directories like `lib`, `test`, `priv`, and `config`. We'll name modules to match their file paths, establish boundaries to keep the project navigable as it expands.\n\nIn this example, we'll use Elixir version 1.20.1; while the operations should be consistent across versions, minor differences may occur. This article marks a significant shift in the series, moving from pasting examples into IEx to writing everything in real files within a Mix project. Each code block will show the file path, and all examples will be validated with `mix run`, displaying the output immediately after. When we simply need to interact with our functions, `iex -S mix` will restart the interactive shell, now aware of the compiled project.\n\nAnatomy of the Default Project\nHere is the entire output generated by `mix new learning_elixir`:\n\n```\nlearning_elixir/\n├── .formatter.exs\n├── .gitignore\n├── README.md\n├── lib/\n│ └── learning_elixir.ex\n├── mix.exs\n└── test/\n├── learning_elixir_test.exs\n└── test_helper.exs\n```\n\n`lib/` — Application Code\nThe core of the project resides in the `lib/` directory. All `.ex` files under this directory are compiled into the application. The starter module generated by `mix new` looks like this:\n\n```elixir\n# lib/learning_elixir.ex\ndefmodule LearningElixir do\n@moduledoc \"Documentation for `LearningElixir`.\"\n\n@doc \"Hello world.\"\ndef hello do\n:world\nend\nend\n```\n\n`mix.exs` — The Project Definition\nThe `mix.exs` file defines the project's metadata and dependencies. This file is essential for Mix to compile, test, and manage the project. The structure of `mix.exs` is as follows:\n\n```elixir\ndefmodule LearningElixir.MixProject do\nuse Mix.Project\n\ndef project do\n[\napp: :learning_elixir,\nversion: \"0.1.0\",\nelixir: \"~> 1.20\",\nstart_permanent: Mix.env() == :prod,\ndeps: deps()\n]\nend\n\n# Additional functions for project configuration\nend\n```\n\n`test/` — Test Suite\nThe `test/` directory contains tests for the application's functionality. The default setup includes a test helper and the first test file:\n\n```elixir\n# test/learning_elixir_test.exs\ndefmodule LearningElixirTest do\nuse ExUnit.Case\n\ntest \"hello world\" do\nassert LearningElixir.hello() == :world\nend\nend\n```\n\nAdditional Directories\n`priv/` — Non-Code Assets\nThis directory is intended for non-code assets that the application ships with, such as images or configuration files. Configuration files in this directory can be accessed during runtime.\n\n`config/` — Configuration Files\nConfiguration files separate runtime settings from the application's code. They can be customized for different environments like development, testing, or production using environment variables.\n\nPractical Guidelines\nThe structure outlined above is not enforced by the compiler but provides a convention that makes it easier to read and maintain other developers' code. Each directory and file serves a specific purpose, ensuring that as the project grows, it remains organized and scalable.\n\nConclusion\nUnderstanding and applying a well-defined project structure is crucial for managing larger Elixir projects. By following these guidelines, developers can ensure their projects are organized, maintainable, and scalable.",
  "summary": "When an Elixir project outgrows a handful of modules, the habit of pasting definitions into IEx starts to break down — redefinition warnings pile up, names collide, and nothing survives the session. One way to picture what comes next is a workshop: it begins as a single shelf of drawers and, as the work grows, turns into a whole room with labeled aisles and a storage room for materials that are…",
  "key_points": [
    "Project structure maps modules to file system for manageability",
    "lib/ directory holds application code, test/ contains tests",
    "mix.exs defines project metadata, dependencies, and start behavior"
  ],
  "editors_take": null,
  "illustration": null,
  "coverage": {
    "outlets": 1,
    "also_reported_by": []
  },
  "ai_generated": true,
  "disclaimer": "Summaries, key points and the editor’s take are written by software from other outlets’ reporting and may contain errors — always check the linked original."
}