The Tiny Elixir Guidebook
Learn Elixir from zero through building real projects. No CS degree required. Friendly, analogy-first approach to functional programming.
Table of Contents
Welcome to Elixir
Get started with Elixir: installation, your first program, and understanding why Elixir is different.
- The System That Never Stops12 min
Imagine you run a factory floor. One night, a critical machine breaks down. In most factories, this means disaster—production stops, orders pile up, and you lose money. But your factory is different. When a machine breaks, a maintenance team immediately replaces it with a spare, a new crew steps in, and production continues as if nothing happened. Your clients never even notice. This is what programming in Elixir feels like. The Problem with Most Programming Languages When you write code in most languages (Python, JavaScript, Ruby), your program is like a single worker trying to handle every task. If that worker makes a mistake, gets overwhelmed, or just has a bad day, the entire operation stops. Here's what typically happens: One bug can crash your entire application When traffic spikes, your app slows down or dies Fixing problems requires stopping everything (deployments at 3 AM) You've probably experienced this. A website you use goes down. An app crashes. "We'll be back shortly!" they say. As a user, you wait. As a programmer, you dread causing this pain. Elixir's Different Approach Elixir runs on something called the BEAM (don't worry about the acronym). Think of the BEAM as a…
- The Restaurant That Never Closes12 min
Imagine you own a restaurant. One night, a fire breaks out in the kitchen. In most restaurants, this means disaster—dinner service stops, customers leave angry, and you lose money. But your restaurant is different. When the kitchen catches fire, a team of firefighters immediately extinguishes it, a new kitchen crew materializes from nowhere, and dinner service continues as if nothing happened. Your customers never even notice. This is what programming in Elixir feels like. The Problem with Most Programming Languages When you write code in most languages (Python, JavaScript, Ruby), your program is like a single chef trying to cook every meal. If that chef cuts their finger, burns a dish, or just has a bad day, the entire restaurant stops. Here's what typically happens: One bug can crash your entire application When traffic spikes, your app slows down or dies Fixing problems requires stopping everything (deployments at 3 AM) You've probably experienced this. A website you use goes down. An app crashes. "We'll be back shortly!" they say. As a user, you wait. As a programmer, you dread causing this pain. Elixir's Different Approach Elixir runs on something called the BEAM (don't worry…
- Setting Up Your Development Environment15 min
Before we build, we need our tools. Before we code, we need Elixir installed. The good news: installing Elixir is easier than ever. The bad news: every computer is slightly different, so we need to handle a few cases. Don't worry—if you get stuck, there's a friendly community ready to help (we'll cover that in the next chapter). What We're Installing When you "install Elixir," you're actually getting three tools: Elixir - The programming language itself IEx - Interactive Elixir (your playground) Mix - A build tool for creating projects Think of these like setting up a workbench: Elixir = The raw materials and components IEx = The workbench where you test and experiment Mix = The project organizer that keeps everything structured Installing on macOS If you have a Mac, the easiest way is using Homebrew (a package manager for Mac). Step 1: Open Terminal ( press Cmd + Space, type "Terminal", press Enter) Step 2: Install Homebrew if you don't have it: Step 3: Install Elixir: Wait a few minutes. Homebrew will download and install everything automatically. Step 4: Verify it worked: You should see something like: (The exact numbers don't matter—just that you see "Elixir" and a version.)…
- Getting Your Kitchen Ready15 min
Before we cook, we need a kitchen. Before we code, we need Elixir installed. The good news: installing Elixir is easier than ever. The bad news: every computer is slightly different, so we need to handle a few cases. Don't worry—if you get stuck, there's a friendly community ready to help (we'll cover that in the next chapter). What We're Installing When you "install Elixir," you're actually getting three tools: Elixir - The programming language itself IEx - Interactive Elixir (your playground) Mix - A build tool for creating projects Think of these like: Elixir = The cooking ingredients IEx = A test kitchen where you experiment Mix = A recipe organizer and kitchen manager Installing on macOS If you have a Mac, the easiest way is using Homebrew (a package manager for Mac). Step 1: Open Terminal ( press Cmd + Space, type "Terminal", press Enter) Step 2: Install Homebrew if you don't have it: Step 3: Install Elixir: Wait a few minutes. Homebrew will download and install everything automatically. Step 4: Verify it worked: You should see something like: (The exact numbers don't matter—just that you see "Elixir" and a version.) Installing on Windows Windows has a couple of options.…
- The Magic Calculator18 min
You know what's annoying? Splitting a shared expense among teammates. "The total is $127.43 including tax, and we need to add 18% service fee, and there are 5 of us, but Sarah only used $15 worth of supplies..." Your phone's calculator wasn't built for this. But Elixir was. In this chapter, you'll build a tip calculator that handles all the weird edge cases. By the end, you'll have written actual Elixir code that solves a real problem. Our Goal We want a calculator that: Takes a bill amount Adds a tip percentage Splits it evenly (or handles "Sarah only used $15 worth of supplies") Shows exactly what each person pays Creating Your First Elixir File Elixir files end with .ex (for compiled code) or .exs (for scripts we'll run once). Step 1: Create a new folder for your code: Open your terminal/command prompt Navigate to where you want your code (Desktop, Documents, wherever) Create a folder: Step 2: Create a file called tipcalculator.exs: **macOS/Linux:** touch tipcalculator.exs Windows: type nul > tipcalculator.exs Or just use your text editor (VS Code, Sublime, Notepad, whatever) and save an empty file as tipcalculator.exs. Step 3: Open the file in your editor. Writing the Basic…
The Building Blocks
Learn Elixir's fundamental types and structures: numbers, lists, maps, pattern matching, and control flow.
- Labels, Numbers, and Secrets Free with email20 min
Imagine you're organizing your closet. You wouldn't toss everything into one big pile—you'd put socks in a sock drawer, hang up shirts, and maybe have a special box for sentimental stuff you never wear but can't throw away. Elixir is the same way. It wants to know what kind of thing it's holding so it knows what it can do with it. These "kinds of things" are called types. Why Types Matter In your closet, you wouldn't try to fold a hanger or hang a sock. Types tell Elixir what operations make sense. If you try to divide a word by a number, Elixir will complain. This might seem annoying, but it catches mistakes before they become bugs. Numbers: The Calculator You Always Have With You Let's start simple. Open IEx (remember from the last chapter?) and try this: You just created a variable called age and stored the number 30 in it. The = doesn't mean "equals" in the math sense—it means "assign this value to this name." Integers: Whole Numbers Integers are numbers without decimal points: See those underscores? That's just for you. Elixir ignores them, but your eyeballs don't. It's like writing 1,000,000,000 with commas, but programmer-style. Try this: In most programming languages, this…
- The Line at the Coffee Shop Free with email22 min
Picture your favorite coffee shop. There's a line of people waiting to order. This line has special properties: New people join at the end The person at the front gets served first You can't skip ahead without upsetting everyone In programming, we call this a list (or more specifically, a linked list). Now imagine a different scenario: you're giving someone directions to your house. You say: "Go 3 blocks north, then 2 blocks east." These two numbers always go together—you can't reorder them without sending someone to the wrong place. In programming, we call this a tuple. Lists: The Conga Line of Data Lists in Elixir are ordered collections: Creating Lists Accessing List Elements Important: hd and tl are fast. Enum.at has to count from the beginning, so it's slower for big lists. Common List Operations Linked Lists: How They Actually Work Here's where Elixir lists get interesting. They're not like arrays in other languages—they're linked lists. Imagine a treasure hunt where each clue points to the next: Each box (called a cons cell) contains: A value (the number) A pointer to the next box (or to empty [] if it's the last) This is why prepending is fast but appending is slow: Why…
- The Filing Cabinet and the Form Free with email20 min
Imagine you have a filing cabinet. Each drawer has a label, and inside is information related to that label. When you need something, you look at the labels—not the contents of every drawer. In Elixir, we call this a map. Now imagine a form you fill out at the doctor's office. It has specific fields: name, date of birth, insurance number. You can't add random fields—the form defines what information is required. In Elixir, we call this a struct. Maps: Key-Value Storage Maps store data as key-value pairs: Notice the difference: "name" (string key) uses => :name (atom key) uses : after the key name Creating Maps Accessing Map Values Adding and Updating Keys Since Elixir is immutable, we create new maps: Checking for Keys Map Pattern Matching This is one of Elixir's most useful features: Common Map Operations Nested Maps Maps can contain other maps: Structs: Maps with Structure Structs are maps with: A predefined set of keys A default module namespace Compile-time checks Defining a Struct Creating Structs Struct Access Why Use Structs? Documentation: Clear what fields exist Pattern matching: Match on struct type, not just keys Defaults: Keys have sensible defaults Namespacing: Won't…
- The Ultimate Sorting Hat Free with email25 min
Remember the Sorting Hat from Harry Potter? It looks into your mind, sees who you truly are, and declares: "Gryffindor!" or "Ravenclaw!" Pattern matching in Elixir is like that Sorting Hat. It looks at your data, sees what it truly is, and routes it to the right place. It's the most powerful feature in Elixir—and once you get it, you'll wonder how you ever coded without it. The = Operator Is Not Assignment In most languages, = means "put this value in this variable." In Elixir, = means "make the left side match the right side." The = operator tries to make both sides equal. If they already are, great. If not, and the left side is a variable, it binds the value. If the left side can't match, it raises an error. Basic Pattern Matching With Tuples With Lists With Maps The Underscore: "I Don't Care" Use `` (underscore) when you don't care about a value: You can also use name to give the unused variable a name (for documentation): The Pin Operator: ^ Sometimes you want to match against an existing variable's value, not bind to it: Use ^ when you want to match against an existing value. Pattern Matching in Case Statements This is where pattern matching shines: Each branch is a pattern.…
- Decisions, Decisions Free with email20 min
Life is full of choices. Turn left or right? Coffee or tea? Stay in or go out? Code is the same way. Programs need to make decisions based on data, user input, or random chance. In Elixir, we have several tools for this—and they might surprise you if you're coming from other languages. If and Unless Let's start with the familiar: But here's the thing: in Elixir, if is just a macro. Everything is an expression that returns a value: One-Line If For simple cases: Unless unless is if backwards—it runs when the condition is false: Important: Unlike some languages, unless in Elixir cannot have an else clause. If you need both branches, use if. Case: Pattern Matching Control Flow We covered case in the pattern matching chapter, but it's worth repeating: case is your go-to when you need pattern matching. Cond: Multiple Conditions Use cond when you have multiple conditions to check (like if/else if chains in other languages): Important: cond checks conditions in order and returns the first true one. The true -> at the end acts like a default case (like else). With: The Happy Path with is special. It's for when you have a series of operations that might fail, and you want to stop at the…
Functions and Modules
Master functions, modules, the pipe operator, and recursion through hands-on projects.
- Recipes You Can Reuse Free with email20 min
Imagine you're building furniture. You don't look up "how to cut a board to size" every single time—you just cut the board because you know how. Your brain has stored that skill as a reusable procedure. Functions in programming are the same thing. They're reusable blocks of code that do something specific. Once you write a function, you can use it over and over without rewriting the code. Defining Functions Functions live inside modules (we'll cover modules in detail later): def defines a function. The name is add, and it takes two parameters: a and b. Arity: How Many Arguments? In Elixir, add/2 is a different function from add/3. The number after the slash is the arity—the number of arguments. In documentation, you'll see functions written as functionname/arity like Enum.map/2 or String.upcase/1. Pattern Matching in Functions This is where Elixir functions get powerful. Each function clause is a pattern match: The clauses are tried in order, top to bottom. The first one that matches wins. Guards: Conditions on Your Patterns Sometimes you need more than just pattern matching—you need conditions. Use when: Common Guard Expressions **Note:** Guards have limitations. You can't call…
- The One-Time Recipe Free with email18 min
Sometimes you need a recipe you'll only use once. Maybe you're experimenting, or the code is so specific to one situation that naming it would be overkill. Anonymous functions are exactly that—functions without names. They're disposable, single-use, or defined right where you need them. Creating Anonymous Functions Use fn and end: Notice the dot (.) before the parentheses. This is required for anonymous functions to distinguish them from named function calls. Short Syntax: The Capture Operator For simple functions, use &: The numbers (&1, &2, etc.) refer to the arguments by position. More Examples Closures: Remembering Their Environment Anonymous functions can capture variables from their surrounding scope: The function "remembers" the value of multiplier even if it changes later: Higher-Order Functions Functions that take functions as arguments or return functions: Taking Functions as Arguments Returning Functions Common Higher-Order Function Patterns Enum.each Do something for each element: Enum.reduce Accumulate a result: Enum.sortby Sort by a computed value: The & Shortcut for Named Functions Reference an existing function without calling it: The /1 specifies the arity (number…
- Organizing Your Workshop Free with email18 min
Imagine your workshop. You don't throw all your tools, hardware, and materials into one giant pile. You have: A drawer for hand tools A cabinet for power tools A rack for lumber and sheet goods A bin for fasteners and hardware Each container holds related items. When you need a wrench, you know exactly where to look. Modules in Elixir work the same way. They're containers for related functions, keeping your code organized and maintainable. Creating Modules Use defmodule: Module names use CamelCase and must start with a capital letter. Nested Modules Modules can be nested: This creates a hierarchy that matches your code's organization. Module Attributes Module attributes are like constants or metadata: Built-in Module Attributes Import: Bringing Functions Into Scope import lets you use module functions without the module prefix: Import Options Best Practice: Use only: to be explicit about what you're importing. This makes your code clearer. Alias: Shortening Module Names alias creates a shortcut for long module names: Instead of typing MyApp.Models.User every time, you just type User. Custom Aliases Multiple Aliases Require: Using Macros require is needed to use macros from another…
- Organizing Your Kitchen Free with email18 min
Imagine your kitchen. You don't throw all your utensils, ingredients, and appliances into one giant pile. You have: A drawer for silverware A cabinet for pots and pans The fridge for perishables The pantry for dry goods Each container holds related items. When you need a spatula, you know exactly where to look. Modules in Elixir work the same way. They're containers for related functions, keeping your code organized and maintainable. Creating Modules Use defmodule: Module names use CamelCase and must start with a capital letter. Nested Modules Modules can be nested: This creates a hierarchy that matches your code's organization. Module Attributes Module attributes are like constants or metadata: Built-in Module Attributes Import: Bringing Functions Into Scope import lets you use module functions without the module prefix: Import Options Best Practice: Use only: to be explicit about what you're importing. This makes your code clearer. Alias: Shortening Module Names alias creates a shortcut for long module names: Instead of typing MyApp.Models.User every time, you just type User. Custom Aliases Multiple Aliases Require: Using Macros require is needed to use macros from another…
- The Assembly Line Free with email18 min
Imagine an assembly line in a factory. Raw materials enter at one end, go through a series of transformations, and come out as finished products at the other end. Each station on the line does one thing: Cut the metal Drill holes Attach handles Paint Package The pipe operator (|>) in Elixir is like that assembly line. It takes the output of one function and feeds it as the first argument to the next function. The Problem with Nested Calls Without pipes, code gets messy: You have to read from the inside out. The first thing that happens is buried in the middle. The Pipe Operator The |> operator passes the left side as the first argument to the right side: Now you read it like a sentence: Take name Replace underscores with spaces Trim whitespace Convert to uppercase How It Works The result of each step becomes the first argument of the next: Real Examples Processing a List Working with Maps Data Transformation Pipeline Each function receives the result of the previous and returns something for the next. Pipes with Multi-Argument Functions What if a function needs more than one argument? Using Anonymous Functions Or with captures: The Tap Function Sometimes you want to peek at the…
- The Never-Ending Story (That Ends) Free with email22 min
Imagine a set of Russian nesting dolls. You open the biggest one, and inside is a smaller one. You open that, and there's an even smaller one. This continues until you reach the tiniest doll—the one that doesn't open. Recursion in programming is like those nesting dolls. A function calls itself with a smaller problem, until it reaches the simplest case that doesn't need recursion. Why Recursion? In Elixir (and functional programming in general), we avoid changing state. Loops in other languages usually require modifying a counter: In Elixir, we use recursion instead: The Two Parts of Recursion Every recursive function needs: Base case - When to stop (the smallest doll) Recursive case - Call yourself with a smaller problem Visual: Tail Recursion The version above builds up a stack of pending operations. For large lists, this can cause a "stack overflow." Tail recursion solves this by passing an accumulator: Visual: No pending operations! Elixir optimizes this to use constant stack space. Common Recursive Patterns Count Map (Transform Each Element) Filter Reverse Multiple Recursive Cases Your Mini-Project 1: File System Explorer Create fileexplorer.exs: Your Mini-Project 2: Number…
Data Structures Deep Dive
Understand computer science fundamentals: linked lists, stacks, queues, graphs, and trees explained simply.
- Following the Breadcrumbs Free with email20 min
Imagine you're on a treasure hunt. You find a note that says: "Dig under the oak tree." At the oak tree, you find another note: "Look behind the waterfall." Behind the waterfall, another note: "Check the old well." Each clue points to the next location. This is exactly how a linked list works. What Is a Linked List? A linked list is a chain of elements where each element contains: Some data (the treasure) A pointer to the next element (the next clue) In Elixir, when you write [1, 2, 3], you're actually creating a linked list. Linked List vs Array Arrays (in other languages like Python or JavaScript) are like a row of mailboxes: Each mailbox has a number (index) You can jump directly to mailbox #5 But inserting a new mailbox means shifting all the others Linked lists are like our treasure hunt: To find clue #5, you must follow clues 1-4 But adding a new clue just means updating one pointer Linked Lists in Elixir Elixir lists are actually linked lists under the hood. The [head | tail] syntax reveals this: Visualizing [1, 2, 3] Breaking it down: [1 | ->] points to [2 | ->] [2 | ->] points to [3 | ->] [3 | ->] points to [] (empty list) [] means "the end" Building a Linked List from…
- Piles and Lines Free with email18 min
Imagine two scenarios: Scenario 1: A Pile of Plates You stack clean plates on top of each other. When you need a plate, you take the one from the top—the one you just put there. This is a stack: Last In, First Out (LIFO). Scenario 2: A Line at the Movies People arrive and join the back of the line. The person at the front gets served first—the one who arrived earliest. This is a queue: First In, First Out (FIFO). These two data structures solve different problems, and Elixir lists can implement both. Stacks: Last In, First Out (LIFO) Think of a stack of books: Operations: Push: Add to the top Pop: Remove from the top Peek: Look at the top without removing Stack with Elixir Lists Lists are perfect for stacks because prepending is O(1): Real-World Stack: Undo System Create undosystem.exs: Queues: First In, First Out (FIFO) Think of a queue at the DMV: Operations: **Enqueue**: Add to the back **Dequeue**: Remove from the front **Peek**: Look at the front Naive Queue (Don't Do This) Appending to a list is O(n). For a busy queue, this is terrible. Better Queue: Two Stacks Use two…
- The Social Network Free with email22 min
How does Facebook know who you might know? How does Google Maps find the fastest route? How does your package get from a warehouse to your door? The answer is graphs. What Is a Graph? A graph is a collection of: Nodes (also called vertices): The things (people, places, web pages) Edges: The connections between things (friendships, roads, links) In this graph: Nodes: Alice, Bob, Charlie, Diana, Eve Edges: Alice-Bob, Alice-Charlie, Bob-Diana, Charlie-Eve Types of Graphs Undirected vs Directed Undirected: Relationships go both ways (friendship) If Alice is friends with Bob, Bob is friends with Alice. Directed: Relationships have direction (following, links) Alice follows Bob, but Bob might not follow Alice. Weighted vs Unweighted Unweighted: All connections are equal Weighted: Connections have values (distance, cost, strength) From A to C through B costs 7 (5 + 2). Representing Graphs in Elixir Adjacency List Most common approach—each node knows its neighbors: Adjacency Matrix A grid showing connections: In Elixir: For most applications, adjacency lists are simpler and more efficient. Graph Traversal How do you visit all nodes? Two main approaches: Breadth-First Search (BFS) Explore…
- Family Trees and File Systems Free with email20 min
Imagine your family tree. You at the bottom, your parents above you, their parents above them. Everyone has one position, everyone connects upward. Now imagine your computer's file system. Folders inside folders. Documents inside folders. Each folder can contain more folders or files. These are trees—hierarchical structures where every element (except the top one) has exactly one parent. What Is a Tree? A tree is a special kind of graph: Root: The top node (has no parent) Nodes: All elements in the tree Children: Nodes directly below a parent Parent: The node directly above Leaves: Nodes with no children (at the bottom) Depth: How many levels down from the root Types of Trees Binary Tree Each node has at most 2 children: Binary Search Tree (BST) Left children are smaller, right children are larger: Searching for 7: 10 → 5 → 7 (fast!) N-ary Tree Nodes can have any number of children (file system, DOM): Representing Trees in Elixir Common approach: node with value and list of children: Or with a struct: Tree Traversal How do you visit every node? Depth-First Search (DFS) Go deep before going wide. Pre-order (visit node, then children): Post-order (visit children, then node):…
The Elixir Way
Learn Elixir's philosophy: immutability, writing readable code, using Credo, and testing your code.
- Nothing Changes, Everything Transforms Free with email18 min
Imagine you could time travel. You go back to yesterday and change one small thing. Suddenly, everything from that point forward is different. Your memories change. Your relationships change. The world changes. In most programming, data works like this. When you "change" a variable, you're actually changing it for everything that comes after. One small change can cascade through your entire program in unpredictable ways. Elixir does something different: immutability. In Elixir, data never changes. Instead, you create new data based on the old. The Problem with Mutability Here's how most languages work: Seems fine, right? But what about: We only wanted to add Carol to admins, but we accidentally modified the original list too. This is called aliasing—multiple names for the same mutable data. These bugs are: Common: Happen all the time in mutable languages Hard to find: The problem might be far from where you notice it Hard to reason about: To understand code, you must track every possible mutation How Immutability Works In Elixir, data never changes. Ever. When you "modify" something, you get a completely new thing: Why Immutability Is Awesome No Aliasing Bugs Easy to Reason About…
- Writing Code Others Want to Read Free with email18 min
Have you ever opened a file and immediately thought, "I don't want to deal with this"? The code is messy, names don't make sense, and nothing is organized. You spend 20 minutes just figuring out what's going on. Now imagine opening a file where everything is clear. Names tell you exactly what things do. The structure follows a pattern you recognize. You can understand it at a glance. Good style isn't about being pedantic—it's about being kind to the person reading your code (which might be you, six months from now). The Golden Rule Code is read 10x more than it's written. Optimize for readability. Future-you will thank present-you. Naming Conventions Modules: PascalCase Functions and Variables: snakecase Atoms: snakecase (unless part of a larger name) Predicate Functions: End with ? Functions that return boolean should end with ?: Important: Never use is prefix for regular functions. That's reserved for guard-safe macros like isinteger/1. Bang Functions: End with ! Functions that raise on error should end with !: Use the non-bang version by default. Use the bang version when: Failure should stop everything You're sure it won't fail You're in a quick script (not production) Function…
- Your Friendly Robot Critic Free with email15 min
Imagine having a very picky English teacher who reads your code and points out every style issue, potential bug, and questionable design decision. That's Credo. Credo is a static analysis tool for Elixir. It doesn't run your code—it reads it and tells you what could be better. Why Use Credo? Catches bugs before they happen Unused variables Deprecated functions Potential runtime errors Enforces consistency Naming conventions Code structure Documentation standards Teaches best practices Suggests better patterns Explains why something is an issue Helps you learn as you go Automated code review Runs in CI/CD Catches issues before human review Keeps code quality high Installing Credo Add to your mix.exs: Then: Running Credo Basic Usage Output Example Severity levels: [F] → Fatal (code won't compile/work) [C] → Consistency (style issues) [W] → Warning (potential bugs) [R] → Refactoring opportunity [D] → Software design suggestion Common Issues Credo Catches Unused Variables Deep Nesting Missing Documentation Pipe Chain Should Start with a Raw Value Predicate Naming Configuration Create .credo.exs to customize: Your Mini-Project:…
- Breaking Things on Purpose Free with email20 min
Imagine you buy a car. The manufacturer says, "We didn't test it, but we're pretty sure it works." You'd be horrified, right? Software is the same way. Without testing, you're just hoping your code works. Testing proves it works—and keeps working as you make changes. Why Test? Confidence: Know your code works Documentation: Tests show how code should be used Safety net: Catch breaking changes immediately Design: Testable code is usually better designed Refactoring: Change things without fear ExUnit: Elixir's Testing Framework ExUnit is built into Elixir. No installation needed. Your First Test Create test/example_test.exs: Run it: Output: Assertions Basic Assertions Match Assertions Exception Assertions Test…
Introduction to OTP
Discover Elixir's superpower: lightweight processes, supervisors that heal crashes, and GenServers for state.
- Tiny Computers Inside Your Computer Free with email22 min
Remember our factory analogy from Chapter 1? Instead of one worker trying to handle everything, Elixir has thousands of isolated workers—each one completely independent, each one working on its own task. In Elixir, these "workers" are called processes. And unlike operating system processes (which are heavy), Elixir processes are extremely lightweight—you can have millions of them running at once. What Is a Process? A process in Elixir is: An independent unit of execution Has its own memory (isolated from others) Communicates only by sending messages Very lightweight (~300 words of memory to start) Think of processes like people in an office: Each person has their own desk (memory) They work independently They communicate by passing notes (messages) If one person has a bad day, it doesn't stop everyone else Creating Processes spawn/1 and spawn/3 Create a new process with spawn: The pid (process identifier) is how you communicate with the process. Your First Process In IEx: Sending and Receiving Messages Processes communicate by sending messages: A Simple Echo Process The receive Block receive waits for messages: Pattern Matching with receive Process Monitoring You can…
- The Healer Free with email20 min
Imagine a hospital where every time a patient has a problem, they just... disappear. No doctors, no treatment, no recovery. That's how most programming languages handle errors. Elixir takes a different approach: supervisors. When a process crashes, a supervisor notices and starts a new one. The system heals itself. This is the "let it crash" philosophy. Don't write defensive code everywhere. Instead, write supervisors that restart processes when they fail. What Is a Supervisor? A supervisor is a special process that: Monitors other processes (its "children") Restarts children when they crash Uses strategies to decide how to restart Can supervise other supervisors (supervision trees) Basic Supervisor Example Restart Strategies :oneforone If one child crashes, restart only that child: Best for: Independent processes :oneforall If one child crashes, restart all children: Best for: Dependent processes :restforone If a child crashes, restart that child and all children started after it: Best for: Sequential dependencies Child Specifications When you add a child to a supervisor, you can specify: Restart Values :permanent - Always restart (default) :temporary -…
- The State Keeper Free with email22 min
Remember our chat room from earlier? It worked, but writing all that receive boilerplate was tedious. And what if we want to: Query the current state? Handle both synchronous and asynchronous requests? Track performance metrics? GenServer (Generic Server) handles all of this for us. It's a behavior (a template) for building stateful processes. What Is GenServer? Think of GenServer like a reliable worker with an inbox: Holds state (remembers information between calls) Handles requests (respond to messages) Runs reliably (can be supervised) A Simple GenServer Call vs Cast Call (Synchronous) Cast (Asynchronous) Important Callbacks init/1 Called when the server starts: handlecall/3 Handle synchronous requests: handlecast/2 Handle asynchronous requests: handleinfo/2 Handle unexpected messages: Your Mini-Project: Shared Todo List Create todoserver.exs: Run it: Linking and Monitoring Starting with a Supervisor Timeout…
Build Your First Project
Put it all together by building LinkBook, a real bookmark manager, and learn where to go next.
- What We're Building Free with email15 min
You know the problem. You bookmark a great article, tutorial, or tool. A month later, you need it. But you can't remember where you saved it, what folder it's in, or what it was even called. Browser bookmarks are too simple. Fancy bookmark apps are too complex. What you need is something in the middle—LinkBook. LinkBook Features A personal bookmark manager with: 🔗 Save URLs with title, description, and notes 🏷️ Tag system for flexible organization 🔍 Search across titles, descriptions, and tags ⭐ Favorites for quick access 📊 Categories for broad organization 💾 Persistent storage (saves to file) 🖥️ Command-line interface for quick use What You'll Learn By building LinkBook, you'll practice: Modules and structs - Organizing your code Maps and lists - Data structures for bookmarks Functions - CRUD operations (Create, Read, Update, Delete) Pattern matching - Handling different inputs elegantly File I/O - Saving and loading data CLI…
- Putting It All Together Free with email35 min
Let's build LinkBook! We'll create each module, explain the code, and put it all together at the end. Step 1: The Bookmark Struct Create lib/bookmark.ex: Step 2: Storage Module Create lib/storage.ex: Step 3: Main LinkBook Module Create lib/linkbook.ex: Step 4: CLI Module Create lib/cli.ex: Step 5: Mix Project Setup Create mix.exs: Building and Running Key Takeaways Built a complete, useful application Practiced structs, pattern…
- Where to Go From Here Free with email18 min
You did it. You went from zero to building a real, working bookmark manager. You understand processes, pattern matching, and functional programming. You can read and write Elixir code. So what now? The Elixir Ecosystem Elixir doesn't exist in a vacuum. It's part of a larger ecosystem that makes it possible to build real web applications, distributed systems, and more. Phoenix: The Web Framework Remember how we built a CLI application? Phoenix lets you build web applications with the same ease. What Phoenix gives you: Routing: Handle HTTP requests Controllers: Organize your web logic Templates: Generate HTML Channels: Real-time features (like chat) PubSub: Broadcast messages across processes The Phoenix hello world: Phoenix is to Elixir what Rails is to Ruby—opinionated, productive, and powerful. LiveView: Real-Time Without JavaScript This is where Elixir really shines. LiveView lets you build interactive web apps without writing JavaScript. How it works: User clicks a button Event goes to the server Your Elixir code updates the state LiveView sends only the changed HTML to the browser Browser updates automatically Example: A live counter No JavaScript. No frontend framework. Just…