Mix and Dependencies

Elixir Mix build tool, project structure, dependencies, tasks, and configuration

Mix is Elixir’s build tool and project manager. It handles project creation, compilation, testing, dependencies, and more.

Creating a project

mix new my_app              # basic project
mix new my_app --sup        # project with supervision tree
mix new my_app --umbrella   # umbrella project (multiple apps)

Project structure

my_app/
├── mix.exs            # Project definition, deps, config
├── mix.lock            # Locked dependency versions (auto-generated)
├── config/
│   └── config.exs      # Application config
│   └── dev.exs         # Dev environment config
│   └── test.exs        # Test environment config
│   └── prod.exs        # Production config (often secrets)
│   └── releases.exs    # Release config (optional)
├── lib/
│   └── my_app.ex        # Main module
│   └── my_app/          # Additional modules
├── test/
│   ├── test_helper.exs
│   └── my_app_test.exs
├── .formatter.exs       # Code formatter config
└── .gitignore

mix.exs

defmodule MyApp.MixProject do
  use Mix.Project

  def project do
    [
      app: :my_app,
      version: "0.1.0",
      elixir: "~> 1.16",
      start_permanent: Mix.env() == :prod,
      deps: deps(),
      aliases: aliases()
    ]
  end

  def application do
    [
      extra_applications: [:logger],
      mod: {MyApp.Application, []}
    ]
  end

  defp deps do
    [
      {:phoenix, "~> 1.7"},
      {:ecto_sql, "~> 3.10"},
      {:jason, "~> 1.4"},
      {:ex_machina, "~> 2.7", only: :test}
    ]
  end

  defp aliases do
    [
      setup: ["deps.get", "ecto.setup"],
      "ecto.setup": ["ecto.create", "ecto.migrate"],
      "ecto.reset": ["ecto.drop", "ecto.setup"],
      test: ["ecto.create --quiet", "ecto.migrate --quiet", "test"]
    ]
  end
end

Dependency management

mix deps.get              # Fetch deps from mix.exs
mix deps.update phoenix   # Update a specific dep
mix deps.update --all     # Update all deps
mix deps.clean phoenix    # Clean a dep (forces rebuild)
mix deps.clean --all      # Clean all deps
mix deps.tree             # Show dependency tree
mix deps.unlock --all     # Unlock all deps (removes mix.lock entries)

Dependency version syntax

Syntax Meaning
"~> 1.7" ≥ 1.7.0 and < 2.0.0 (minor+patch ok)
"~> 1.7.0" ≥ 1.7.0 and < 1.8.0 (patch only)
">= 1.0.0" Any version ≥ 1.0.0
"== 1.7.1" Exact version
{path: "../local_dep"} Local dependency
{git: "https://github.com/...", tag: "v1.0"} Git dependency

Common Mix tasks

Task Description
mix new name Create new project
mix compile Compile the project
mix test Run tests
mix format Format code
mix run Run default code or script
mix run -e "Expr" Run Elixir expression
mix release Build a production release
mix deps.get Fetch dependencies
mix deps.tree Show dependency tree
mix xref graph Show module dependency graph
mix credo Static analysis (needs credo dep)
mix dialyzer Type analysis (needs dialyxir dep)

Configuration

config/config.exs

import Config

config :my_app,
  greeting: "Hello"

config :my_app, MyApp.Repo,
  database: "my_app_dev",
  hostname: "localhost"

config :logger, :console,
  format: "$time $metadata[$level] $message\n",
  metadata: [:request_id]

import_config "#{config_env()}.exs"

Reading config at runtime

# At compile time (in mix.exs or config)
greeting = Application.get_env(:my_app, :greeting)

# At runtime (preferred for releases)
defmodule MyApp.Config do
  def greeting, do: Application.fetch_env!(:my_app, :greeting)
end

Runtime config (config/runtime.exs)

For values resolved at runtime (e.g., from environment variables):

import Config

config :my_app, MyApp.Repo,
  url: System.get_env("DATABASE_URL") || "ecto://localhost/my_app_dev",
  pool_size: String.to_integer(System.get_env("POOL_SIZE") || "10")

config :my_app, MyAppWeb.Endpoint,
  url: [host: System.get_env("PHX_HOST") || "localhost", port: 443],
  secret_key_base: System.fetch_env!("SECRET_KEY_BASE")

IEx — Interactive Elixir

iex                        # Start REPL
iex -S mix                 # Start REPL with project loaded
iex -S mix phx.server      # Start Phoenix server with REPL

Useful IEx commands

Command Description
h/1 Show documentation (e.g. h Enum.map/2)
i/1 Show type info about a value
t/1 Show type spec (e.g. t Enum.t/0)
s/1 Show spec (e.g. s Enum.map/2)
c "file.exs" Compile and load a file
r Module Recompile a module
v() Last evaluation result
flush() Print and clear mailbox
recompile() Recompile project (in iex -S mix)