Nix - package manager

The functional package manager: packages are values computed from recipes (derivations) with pinned inputs — same inputs → same output, stored content-addressed in /nix/store. Not “install software”; “build a value named git-2.47.1” and reference it.

The model

  • Derivations: pure build recipes — explicit inputs (source hash, dependencies, compiler), no ambient state. Build once, cache (substituters/binary cache), reproduce anywhere.
  • /nix/store: every artifact gets a unique path (/nix/store/x7f3...-git-2.47.1); multiple versions coexist; nothing is overwritten, so nothing breaks mid-change.
  • nixpkgs: the ~100k-package collection, itself a Nix expression tree — the largest, most-hackable package repo in existence.
  • Overlays: patches applied to nixpkgs itself — override a version, patch a CVE, add a package — without forking the whole tree. dinodaizovi (captured): “build security-critical systems using nixpkgs with a nix flake. Burn tokens finding any and every security vulnerability that affects the resulting artifact and fix them using overlays defined in that flake.” And ghuntley: “the world hasn’t figured out yet that you can literally just fix everything with a Nix overlay.”
  • Flakes: hermetic, locked (flake.lock) project-level packaging — inputs pinned by hash, evaluated reproducibly; the 2020s answer to “which nixpkgs?”

What this buys

  1. Reproducibility: dev shell = CI = agent sandbox = Docker image, from one expression. ghuntley’s nix post (captured): clients drift between laptop/CI configs and “are now heading down a path of triplicating that drift with ephemeral sandboxes. This is utter madness… ‘mise for this’? Mise is a low-power, low-IQ tool.”
  2. Atomic changes + rollback: activating a new system generation never mutates the old one; nix-env --rollback / boot the previous generation.
  3. Supply-chain control (Supply Chain Security): pin by hash, patch by overlay, rebuild only what changed; nix-store --verify, SRI-locked inputs.
  4. Composable outputs: the same expression yields a dev shell, a Docker image (dockerTools.buildLayeredImage — with layer dedup), a VM test, a deployed system.

Costs (honesty box)

  • The language tax is real: Nix-the-language (see Nix (language)) is lazy, untyped, dynamically scoped — infamously hard to read.
  • Store churn: /nix/store grows; GC discipline required (nix-collect-garbage).
  • Docs culture historically weak (“read the source”); improving via nix.dev / search.nixos.org / mynixos.com.

Vault kin

The runnable demo: ghuntley/nix-demo (captured 2026-10-07)

nix-demo (OSS) (7★ Nix, ghuntley) — the concepts above as one working repo: patch git once so every force-push flavor is refused (--force, --force-with-lease, +refspec, --mirror) via two ~30-line C patches applied with git.overrideAttrs (old: { patches = old.patches ++ [...]; }) — then that one overlay feeds the devenv shell, a runNixOSTest VM test asserting the guard rail, and a Docker image. The pitch table is the keeper: server-side branch protection “only covers servers you control”; pre-push hooks are opt-in and --no-verify-bypassable; forking git means maintaining a fork — Nix makes the fork cheap: “you keep a couple of small patches next to your code and say use git, but with this patch, and every consumer picks it up.” The README doubles as a Nix-in-five-concepts tutorial (derivations = hashed recipes; nixpkgs = one overridable function; overlays; store paths; composable outputs).

The pedagogy entry: “Learn Nix the Fun Way” (2026-10-07)

fmzakari (Farid Zakaria) revamped his talk — now a Typst-migrated slide deck (both deck + the original 2024 blog post captured): the teaching arc is one example all the way down — a two-line what-is-my-ip bash script (curl | jq) becomes a Nix derivation via pkgs.writeShellScriptBin, pinning nixpkgs 24.05 — and the payoff demos this note’s core claims as commands: /nix/store/lr6wl…-what-is-my-ip (content-addressed paths), nix-store --query --graph … | dot (the dependency graph is the product), nix bundle → a tarball that runs on non-Nix Linux (portability guaranteed, not hoped for). Companion in vault: his hiding-my-AI-slop-from-my-Nix-friends post (already captured) — Nix as the containment for agent-written code.

nixzer: the syscall-trace codemod for ansible→nix (2026-10-08)

nixzer (OSS) (3★ Python, experimental, sambacha; captured): “Syscall based codemod to convert ansible and bash to nix, correctly?” — the question mark is honest. The approach is genuinely novel: instead of parsing Ansible YAML or bash and guessing semantics, it runs the workload and captures the actual syscalls (strace, ANTLR StraceLexer/Parser.g4 grammars in-tree), then generates Nix from observed behavior — grounded in the Dozer paper (Horton et al., 2022, in docs/). Components: NixTraceCollector (build-time + runtime traces), ansible_to_nix.py, migrate.nix, example traces in traces/ltrace/. For the vault’s two lanes: it’s a Codemod whose “AST” is the syscall trace — observation-based migration, semantics from execution rather than source parsing (the inverse of OpenRewrite: don’t model the language, model what the code actually does). And it’s directly aimed at the COT Ansible-rewrite problem — the ansible→nix bridge this household has been circling since the ghuntley /nix captures. Experimental, 5 commits, but the idea (traces as ground truth for migration) is the keepable part.