Learning Elixir: Project Structure
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…
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.
In 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.
Anatomy of the Default Project
Here is the entire output generated by `mix new learning_elixir`:
```
learning_elixir/
├── .formatter.exs
├── .gitignore
├── README.md
├── lib/
│ └── learning_elixir.ex
├── mix.exs
└── test/
├── learning_elixir_test.exs
└── test_helper.exs
```
`lib/` — Application Code
The 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:
```elixir
# lib/learning_elixir.ex
defmodule LearningElixir do
@moduledoc "Documentation for `LearningElixir`."
@doc "Hello world."
def hello do
:world
end
end
```
`mix.exs` — The Project Definition
The `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:
```elixir
defmodule LearningElixir.MixProject do
use Mix.Project
def project do
[
app: :learning_elixir,
version: "0.1.0",
elixir: "~> 1.20",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Additional functions for project configuration
end
```
`test/` — Test Suite
The `test/` directory contains tests for the application's functionality. The default setup includes a test helper and the first test file:
```elixir
# test/learning_elixir_test.exs
defmodule LearningElixirTest do
use ExUnit.Case
test "hello world" do
assert LearningElixir.hello() == :world
end
end
```
Additional Directories
`priv/` — Non-Code Assets
This 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.
`config/` — Configuration Files
Configuration files separate runtime settings from the application's code. They can be customized for different environments like development, testing, or production using environment variables.
Practical Guidelines
The 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.
Conclusion
Understanding 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.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.