Skip to content
Mix Projects
step 1/7

Reading — step 1 of 7

Learn

~3 min readMix and Testing

Mix is Elixir's build tool — like cargo for Rust, npm for Node, gradle for Java. It scaffolds projects, manages dependencies, runs tests, builds releases. Programming Elixir treats Mix as essential. Real Elixir code lives in Mix projects.

Note: Judge0 runs Elixir scripts directly without Mix. This lesson is conceptual — the syntax and patterns below would run inside a Mix project.

Creating a project

mix new my_app
cd my_app

This creates:

my_app/
├── lib/
│   └── my_app.ex          # main module
├── test/
│   ├── test_helper.exs
│   └── my_app_test.exs
├── mix.exs                # project configuration
├── .formatter.exs
└── README.md

mix.exs — the project file

defmodule MyApp.MixProject do
    use Mix.Project
    
    def project do
        [
            app: :my_app,
            version: "0.1.0",
            elixir: "~> 1.14",
            start_permanent: Mix.env() == :prod,
            deps: deps()
        ]
    end
    
    def application do
        [
            extra_applications: [:logger],
            mod: {MyApp.Application, []}        # supervision tree starter
        ]
    end
    
    defp deps do
        [
            {:phoenix, "~> 1.7"},
            {:ecto_sql, "~> 3.10"},
            {:postgrex, "~> 0.17"},
            {:credo, "~> 1.7", only: [:dev], runtime: false}
        ]
    end
end

Three key sections:

  • project — name, version, deps source
  • application — runtime config; mod points to the supervision tree root
  • deps — Hex package dependencies (Hex is Elixir's package registry)

Common mix commands

mix deps.get             # fetch dependencies
mix compile              # compile sources
mix test                 # run tests
mix run -e "MyApp.do_thing()"
mix iex -S mix           # IEx shell with project loaded
mix release              # build production release
mix phx.server           # for Phoenix apps

Configuration — config/

# config/config.exs
import Config

config :my_app,
    api_url: "https://api.example.com",
    pool_size: 10

import_config "#{config_env()}.exs"
# config/dev.exs
import Config
config :my_app, debug: true
# config/runtime.exs (loaded at runtime, can use env vars)
import Config

database_url = System.fetch_env!("DATABASE_URL")
config :my_app, MyApp.Repo, url: database_url

Code reads config:

Application.fetch_env!(:my_app, :api_url)
Application.get_env(:my_app, :pool_size, 5)

Application module

For stateful apps, define a supervision tree root:

defmodule MyApp.Application do
    use Application
    
    @impl true
    def start(_type, _args) do
        children = [
            MyApp.Repo,
            {Phoenix.PubSub, name: MyApp.PubSub},
            MyAppWeb.Endpoint
        ]
        
        opts = [strategy: :one_for_one, name: MyApp.Supervisor]
        Supervisor.start_link(children, opts)
    end
end

When the BEAM starts, this start/2 callback runs and starts all the supervised children. On crashes, supervision restarts them. The classic OTP pattern.

Hex — Elixir's package registry

mix hex.search phoenix    # search packages
mix hex.info ecto         # info about a package
mix hex.outdated          # check for newer deps

Deps go in mix.exs. After editing, mix deps.get fetches them. Like Cargo.toml + crates.io for Rust.

Releases — production deployment

MIX_ENV=prod mix release

Produces a self-contained tarball with the BEAM, your code, and deps. No runtime requirements on the server. Run with:

_build/prod/rel/my_app/bin/my_app start

Production Elixir deployments are usually releases.

Common mistakes

  • Hardcoding configuration in code — use config files; use runtime.exs for env-var-driven values.
  • Forgetting mix deps.get after editing mix.exs — deps don't auto-fetch; new code won't compile.
  • Mixing dev/prod config — config/config.exs is for shared, config/{dev,prod,test}.exs for env-specific.
  • Putting GenServer.start_link in random places — supervised children belong in the application's supervision tree, not started ad-hoc.
  • Skipping tests — Mix's test integration is excellent. Use it from day one.

Discussion

Ask a question, share an insight, or help someone who’s stuck.

Sign in to post a comment or reply.

Loading…