100% Free Forever
AI-Powered Learning
Industry Expert Content
Certificates & Badges
Learn At Your Own Pace
Programming

Your First Elixir Program

Write, run, and understand your first Elixir program, from a standalone script to a proper Mix module with functions and a test.

FoundationsBeginner8 min readJul 10, 2026
Analogies

Your First Elixir Program

There are two ways to run Elixir code, and knowing when to use each is part of learning the language's workflow. A standalone .exs script is compiled in memory and executed immediately with the elixir command, ideal for quick experiments. A Mix project, created with mix new, organizes real application code into a compiled, testable structure under lib/ and test/. In this walkthrough you'll build the same small greeting module both ways, first as a throwaway script, then as a proper module inside a Mix project with an automated test.

🏏

Cricket analogy: Writing your first Elixir program is like a young cricketer's first outing, you can either play a quick backyard knock, a standalone script, just to feel the bat, or turn up for a proper nets session with the full academy setup, a Mix project, before playing a real match.

Writing a Standalone Script

Create a file named hello.exs containing a module definition and a call to it, then run it with elixir hello.exs from the terminal; Elixir compiles the module in memory, executes the script top to bottom, and exits, leaving no compiled artifact on disk. Note the file extension: .exs signals a script meant to be run directly, while .ex signals a source file meant to be compiled as part of a project. IO.puts/1 is used here to print output to the terminal, but it always returns the atom :ok, not the text it printed, a detail that matters once you start writing functions meant to be tested.

🏏

Cricket analogy: Running elixir hello.exs is like a quick throwdown session in the nets, the bowling machine processes your delivery immediately and you see the result on the spot, with nothing formally entered into the club's official records.

elixir
# hello.exs
defmodule Greeter do
  def greet(name) when is_binary(name) do
    "Hello, #{name}! Welcome to Elixir."
  end
end

IO.puts(Greeter.greet("Ada"))
bash
$ elixir hello.exs
Hello, Ada! Welcome to Elixir.

Building It as a Mix Module

Inside a Mix project generated with mix new hello_world, the same logic belongs in lib/hello_world.ex as a proper module, and this time greet/1 should return the greeting string rather than print it directly, keeping the function easy to test and reuse. Running iex -S mix from the project root compiles the whole project and drops you into an interactive shell with HelloWorld already loaded, so you can call HelloWorld.greet("Ada") immediately without manually requiring any files, the way you would have to in a plain script.

🏏

Cricket analogy: Adding your function to lib/hello_world.ex is like getting your name permanently entered into a franchise's official squad list, so every future training session, iex -S mix, has you already on the roster and ready to be called upon.

elixir
# lib/hello_world.ex
defmodule HelloWorld do
  @moduledoc "A tiny greeting module."

  def greet(name) when is_binary(name) do
    "Hello, #{name}! Welcome to Elixir."
  end
end
bash
$ iex -S mix
iex(1)> HelloWorld.greet("Ada")
"Hello, Ada! Welcome to Elixir."

.exs files are 'Elixir Script' files, compiled in memory and run immediately, ideal for quick experiments and one-off Mix task scripts. .ex files are compiled to .beam bytecode and cached as part of a project's real modules, such as lib/hello_world.ex, which is why only .ex files are picked up automatically when you run iex -S mix.

Writing Your First Test

ExUnit, Elixir's built-in testing framework, expects test files under test/ named with a _test.exs suffix; mix new already generated test/hello_world_test.exs alongside a test/test_helper.exs that calls ExUnit.start(). Inside the test module, use ExUnit.Case brings in the test/2 macro for defining individual test cases and the assert/1 macro for checking that an expression evaluates truthily, or that both sides of an == comparison are equal. Running mix test from the project root compiles the project and executes every test file, printing a dot for each passing test and a summary of how many tests ran and how many failed.

🏏

Cricket analogy: Writing an ExUnit test with assert is like a coach setting a specific fitness benchmark, say a 12-second sprint, that a player must hit, mix test is match day where every player's benchmark is checked automatically and a pass or fail report is issued.

elixir
# test/hello_world_test.exs
defmodule HelloWorldTest do
  use ExUnit.Case

  test "greet/1 returns a welcome message" do
    assert HelloWorld.greet("Ada") == "Hello, Ada! Welcome to Elixir."
  end
end
bash
$ mix test
.
Finished in 0.03 seconds
1 test, 0 failures

IO.puts/1 prints to standard output but always returns :ok, don't confuse a function whose job is printing with one whose job is returning a usable value. If you need the greeting string itself, to test it or send it elsewhere, write a function that returns the string, and let the caller decide whether to print it.

  • Elixir code can run as a standalone .exs script via elixir script.exs, with no compilation artifact left behind.
  • .ex files are meant for real project modules and are compiled to .beam bytecode.
  • defmodule defines a module; functions inside it are defined with def, public, or defp, private.
  • iex -S mix starts an interactive shell with your Mix project's modules already compiled and loaded.
  • ExUnit is Elixir's built-in testing framework; test files live in test/ and end in _test.exs.
  • assert is the primary macro used inside ExUnit tests to check that an expression evaluates as expected.
  • mix test compiles the project and runs the full ExUnit test suite, reporting pass and fail counts.

Practice what you learned

Was this page helpful?

Topics covered

#Programming#ElixirStudyNotes#YourFirstElixirProgram#Elixir#Program#Writing#Standalone#StudyNotes#SkillVeris#ExamPrep