Elixir Cheatsheet
Mix, Testing, and Tooling
Use this Elixir reference while you build software engineering projects, review code, or refresh the syntax you reach for most.
Mix Project Commands
mix new demo # library/app skeleton (--sup for a supervision tree) mix compile mix test mix format mix deps.get mix deps.update package_name mix hex.info package_name mix run -e 'IO.puts(Demo.hello())' mix xref graph --label compile-connected # find compile-time dependencies
Mix is the build tool: it compiles code, manages dependencies, runs tests, formats files, and hosts custom tasks (lib/mix/tasks/*.ex).
mix.exs Essentials
def project do [ app: :demo, version: "0.1.0", elixir: "~> 1.18", deps: deps() ] end def application do [extra_applications: [:logger], mod: {Demo.Application, []}] end defp deps do [ {:jason, "~> 1.4"}, {:req, "~> 0.5"}, {:credo, "~> 1.7", only: [:dev, :test], runtime: false} ] end
elixir: "~> 1.18" is a minimum requirement, not a pin. mix.lock records resolved dependency versions — commit it for applications.
ExUnit Basics
# test/demo_test.exs defmodule DemoTest do use ExUnit.Case, async: true test "adds numbers" do assert Demo.add(2, 3) == 5 end end
Use async: true for tests that do not share global state, databases, files, or named processes. test/test_helper.exs runs first and calls ExUnit.start().
Assertions
assert value == 3 refute Enum.empty?(items) assert {:ok, user} = Accounts.create_user(attrs) # pattern-match assertion assert_raise ArgumentError, fn -> bad_call() end assert_receive {:done, _}, 500 # message-passing tests assert_in_delta 0.1 + 0.2, 0.3, 1.0e-9
Pattern matching inside assert is idiomatic for tagged results, and failures print a diff of the match.
Doctests
defmodule MathBox do @doc """ iex> MathBox.double(4) 8 """ def double(n), do: n * 2 end
defmodule MathBoxTest do use ExUnit.Case, async: true doctest MathBox end
Doctests keep examples executable. Use them for small deterministic functions, not complex setup.
Formatting, Credo, Dialyzer
mix format # standard formatter (config: .formatter.exs) mix format --check-formatted # CI check mix credo --strict # style/design lints mix dialyzer # success typing (dep: dialyxir) mix test --cover # coverage report
IEx Debugging
dbg(value) # prints code + value; pipes show each step IO.inspect(value, label: "value") require IEx; IEx.pry() # breakpoint (run under iex -S mix)
iex -S mix # project shell; recompile with `recompile` iex -S mix test # pry inside tests needs --trace or a timeout bump h Enum.map # docs in IEx; i value — type info
Application Config
# config/config.exs — compile time config :demo, feature_flags: [beta: true] # config/runtime.exs — boot time, right place for env vars config :demo, Demo.Repo, url: System.fetch_env!("DATABASE_URL") # reading Application.fetch_env!(:demo, :feature_flags) Application.get_env(:demo, :missing, :default)
Runtime secrets come from environment variables or a secret manager via config/runtime.exs, never committed config files.