Skip to content

Curriculum

The whole path

01

Foundations

The store, the CLI, and a dev shell you use every day.

  1. Why Nix Explain what problem Nix solves that pacman, mise and Docker do not, and name its three layers. 10 min
  2. Install Nix on Arch Know exactly what your Nix install consists of, where its config lives, and how to remove it cleanly. 10 min
  3. The Nix store Read a store path, compute a package's closure, and reclaim disk space without breaking anything you use. 15 min
  4. Run, shell, search Run any of 28000+ packages without installing it, open a temporary shell with tools, and find package names. 12 min
  5. Dev shells Write a flake.nix that pins Node, pnpm and Biome for a SvelteKit project and enter it with nix develop. 20 min
  6. direnv workflow Make the dev shell load into your fish session automatically on cd, with nix-direnv caching so it is instant. 15 min

02

The language

A small lazy functional language. Learn all of it.

  1. Values and literals Write every primitive Nix value correctly, including the two that bite TypeScript people: lists and paths. 15 min
  2. Attrsets, let, with, inherit Build and merge attribute sets, bind names with let and inherit, and predict exactly what with brings into scope. 18 min
  3. Functions Write and call Nix functions with positional and attrset arguments, and read any package.nix as a function. 18 min
  4. Laziness and recursion Predict what Nix evaluates and what it skips, force evaluation on purpose, and read a fixpoint. 18 min
  5. Builtins and lib Tell builtins from lib, use the ten functions that cover most real code, and find the rest fast. 18 min
  6. The Nix REPL Use nix repl to load files and flakes, inspect nixpkgs interactively, and read docs without leaving the terminal. 15 min
  7. Reading errors Read a Nix error trace bottom-up, recognise the five common messages, and bisect a broken expression in minutes. 18 min

03

Flakes

Inputs, lock files, and the output schema every command reads.

  1. Flake anatomy Read any flake.nix and name its four parts, and explain why flakes replaced channels. 12 min
  2. Inputs and the lock file Declare inputs in every URL form, dedupe nixpkgs with follows, and read flake.lock line by line. 14 min
  3. The outputs schema Name every standard flake output and know which nix command consumes each one. 12 min
  4. Dev shells in depth Build a complete SvelteKit + Turso dev shell with Node 22, pnpm, Biome and turso-cli, plus a CI variant. 15 min
  5. Per-system outputs Remove the x86_64-linux repetition with lib.genAttrs and judge when flake-utils or flake-parts is worth it. 12 min
  6. Flake templates Scaffold new projects from official or personal templates with nix flake init and nix flake new. 10 min
  7. Updating and pinning Update one input at a time, pin to exact revisions, review flake.lock diffs, and test an update without committing. 12 min

04

Derivations and packaging

What a build actually is, and how to bend nixpkgs.

  1. The derivation primitive Build a derivation by hand with builtins.derivation and read its .drv to see exactly what Nix records. 14 min
  2. mkDerivation and phases Package a source tree with stdenv.mkDerivation and control each build phase from unpack to fixup. 15 min
  3. Fetchers and hashes Fetch sources with fetchurl and fetchFromGitHub, get the right SRI hash, and explain why network access needs a hash. 14 min
  4. override and overrideAttrs Change a package's inputs with .override and its build recipe with .overrideAttrs, and know which one a change needs. 13 min
  5. Overlays Change a package for every consumer in a nixpkgs instance with a final: prev: overlay and export it from a flake. 13 min
  6. Language builders Package Node, pnpm, Go and Rust projects with nixpkgs builders, and know when a dev shell is the better answer. 15 min
  7. Debugging builds Read build logs, keep and inspect failed build directories, rerun phases by hand, and trace closures. 15 min

05

Home Manager and modules

The module system, then your dotfiles declared in it.

  1. The module system Evaluate modules with lib.evalModules and predict how options, mkIf, mkMerge and priorities combine. 20 min
  2. Install home-manager on Arch Set up standalone, flake-based home-manager next to pacman, switch, inspect generations and roll back. 20 min
  3. fish, Neovim and git as options Declare your shell, editor and git config with home-manager options instead of hand-managed dotfiles. 20 min
  4. Migrate from chezmoi Move dotfiles from chezmoi to home-manager one program at a time without a broken shell in between. 15 min
  5. Write your own module Design an enable-gated module with typed, documented options, submodules and a modules/ directory. 20 min

06

NixOS and deployment

A whole machine from one repo, on a VM, a laptop, a VPS.

  1. Anatomy of configuration.nix Read and evaluate a complete NixOS configuration on Arch, and know what each nixos-rebuild action does. 20 min
  2. Flake-based NixOS Define laptop and VPS as nixosConfigurations in one flake, pass inputs with specialArgs, and attach home-manager. 20 min
  3. Test NixOS in a VM first Build any nixosConfiguration as a QEMU VM, size it, forward ports, and know what the VM does not test. 15 min
  4. Services and systemd units Turn your systemd --user Python bot into a hardened NixOS system service with a timer, verified by evaluation. 20 min
  5. Secrets management Keep tokens out of the Nix store with agenix or sops-nix and hand them to services at runtime. 15 min
  6. Deploy to the VPS Convert the VPS to NixOS with nixos-anywhere, then push every change from your laptop with nixos-rebuild --target-host. 20 min
  7. The Omarchy desktop, declared Reproduce Hyprland, Waybar, greetd, PipeWire, fonts, LUKS and btrfs as NixOS options, and know what gets harder. 20 min