Mix Projects

Version requirements: "~> 1.4" (≥1.4.0, <2.0.0), "~> 1.4.2" (≥1.4.2, <1.5.0), ">= 1.0.0 and < 2.0.0".

26.1 Creating projects

mix new my_lib                 # library
mix new my_app --sup           # app with a supervision tree
mix new my_umbrella --umbrella # umbrella project (multiple apps)

26.2 mix.exs

Version requirements: "~> 1.4" (≥1.4.0, <2.0.0), "~> 1.4.2" (≥1.4.2, <1.5.0), ">= 1.0.0 and < 2.0.0".

defmodule MyApp.MixProject do
  use Mix.Project

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

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

  defp deps do
    [
      {:jason, "~> 1.4"},
      {:req, "~> 0.5"},
      {:credo, "~> 1.7", only: [:dev, :test], runtime: false},
      {:my_dep, path: "../my_dep"},
      {:other, git: "https://github.com/x/other.git", tag: "v1.0"}
    ]
  end

  defp aliases, do: [setup: ["deps.get", "ecto.setup"], test: ["ecto.create --quiet", "test"]]
  defp elixirc_paths(:test), do: ["lib", "test/support"]
  defp elixirc_paths(_), do: ["lib"]
end

26.3 Common Mix tasks

mix deps.get / deps.update --all / deps.tree / deps.unlock --unused / hex.outdated
mix compile --warnings-as-errors
mix run / mix run --no-halt
mix test / mix test test/foo_test.exs:42 / mix test --failed / --cover / --stale
mix format / mix format --check-formatted
mix docs
mix release
mix xref graph / mix xref callers MyMod
mix help / mix help compile
mix hex.publish
mix profile.fprof / mix profile.eprof / mix profile.tprof

26.4 Configuration

Environments: MIX_ENV=dev|test|prod.

config/
├── config.exs     # compile-time, all environments
├── dev.exs
├── test.exs
├── prod.exs
└── runtime.exs    # executed at boot (releases too) — put secrets/env vars here
# config/config.exs
import Config
config :my_app, timeout: 5_000
config :my_app, MyApp.Repo, pool_size: 10
import_config "#{config_env()}.exs"

# config/runtime.exs
import Config
if config_env() == :prod do
  config :my_app, MyApp.Repo, url: System.fetch_env!("DATABASE_URL")
end
Application.get_env(:my_app, :timeout)
Application.fetch_env!(:my_app, :timeout)
@timeout Application.compile_env(:my_app, :timeout, 1000)

26.5 Custom Mix tasks

defmodule Mix.Tasks.Hello do
  use Mix.Task
  @shortdoc "Says hello"
  def run(args), do: Mix.shell().info("Hello #{Enum.join(args, " ")}")
end

26.6 Umbrella projects

apps/ directory with multiple Mix apps sharing config and deps; in_umbrella: true deps. An alternative is a "poncho" layout (sibling projects with path deps).