Elixir Cheatsheet

Basics

Use this Elixir reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Running Elixir

elixir script.exs      # run a script
iex                    # interactive shell
iex -S mix             # shell with a Mix project loaded
mix new app_name       # create project
mix test               # run tests
mix format             # format code
mix deps.get           # fetch dependencies
elixir --version       # Elixir + Erlang/OTP versions

Elixir source files use .ex for compiled modules and .exs for scripts and tests.

Hello World and Basic IO

IO.puts("Hello, Elixir")            # prints with trailing newline
IO.write("no newline")
name = IO.gets("Name? ") |> String.trim()

IO.inspect([1, 2, 3], label: "nums")  # debug-print any term, returns it
value |> IO.inspect(label: "step") |> next_fun()  # inspect inside a pipeline
dbg(some_expr)                        # macro: prints code + value (great in iex)

IO.inspect/2 returns its argument, so it can be dropped into the middle of any pipeline.

Common Values

42                 # integer (arbitrary precision)
1_000_000          # underscores for readability
0xFF               # hex (255); also 0b1010 binary, 0o777 octal
3.14               # float
1.0e-3             # float with exponent
true               # boolean
false
nil                # absence of value
:ok                # atom
"hello"            # UTF-8 binary string
~c"hello"          # charlist (list of code points), only for Erlang interop

Atoms are constants whose name is their value: :ok, :error, :admin. Booleans and nil are atoms too. Note the charlist sigil ~c"hello" — the old single-quote literal 'hello' is soft-deprecated since Elixir 1.15 and mix format rewrites it to the sigil form.

Names and Rebinding

count = 1
count = count + 1  # rebinding name to a new value, not mutating old value

Data is immutable. Rebinding a name points that name at a new value; existing values are unchanged.

Operators

CategoryOperators
Arithmetic+ - * / div(a,b) rem(a,b)
Comparison== != === !== < > <= >=
Booleanand or not for booleans only
Truthy&& || ! for truthy/falsy values
Concatenate binaries<>
List append / subtractlist ++ other, list -- other
List prepend[x | list]
Pipelinevalue |> function()

Only false and nil are falsy. Everything else is truthy. / always returns a float; use div/2 and rem/2 for integer division. === also distinguishes 1 from 1.0.

if and unless

if age >= 18 do
  :adult
else
  :minor
end

if valid?, do: save(record), else: {:error, :invalid}

unless Enum.empty?(items), do: process(items)   # if-not; formatter-era style prefers if !…

if is an expression — it returns the value of the taken branch (nil when there is no else and the condition is falsy). There is no elsif: use cond or case for multi-way branches (see Pattern Matching). Since Elixir 1.18 the docs discourage unless in new code in favor of if !cond / if cond == false.

String Interpolation

name = "Ada"
IO.puts("Hello, #{name}")
"1 + 1 = #{1 + 1}"          # any expression interpolates via to_string

Use the String module for text: String.length/1, String.trim/1, String.downcase/1, String.split/2, String.contains?/2, String.replace/3. See the Strings, Binaries, and Sigils topic for the full toolkit.