← back to articles

why i write nix for everything

2025-11-14 · 2 min read

reproducible environments are not a luxury. a few notes on how i use nix to keep my dev machines in sync.

i have been using nix for about four years now. it started with a curiosity about reproducible builds and ended with a full takeover of my development environment. every machine i touch — laptop, server, ci runner — boots into the same shell, with the same tools, at the same versions.

the pitch

the standard pitch for nix is reproducibility. you write a derivation, you get a build that produces the same output regardless of where it runs. that part is true and impressive, but it is not why i stayed. i stayed because nix lets me version my entire development environment the same way i version my code.

before nix, every project had a readme section called “setup” that was already out of date. after nix, that section is a single command:

nix develop

the shape of a flake

my standard flake looks something like this:

{
  description = "project environment";

  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
    flake-utils.url = "github:numtide/flake-utils";
  };

  outputs = { self, nixpkgs, flake-utils }:
    flake-utils.lib.eachDefaultSystem (system:
      let pkgs = import nixpkgs { inherit system; };
      in {
        devShells.default = pkgs.mkShell {
          packages = with pkgs; [
            rustc cargo clippy rust-analyzer
            nodejs_22 pnpm
            nil nixfmt-rfc-style
          ];
        };
      });
}

the mkShell call pulls in exactly the compilers, linters, and language servers i need. no global installs, no manual apt-get commands, no “works on my machine”.

what broke

nix is not all wins. the documentation is sprawling and written for people who already understand nix. the error messages are famously opaque. the garbage collector will happily remove something you still need if you are not careful.

but the alternative — maintaining a fragile mental model of what is installed on each machine — costs more over time. nix moves the pain to a single, manageable point: the learning curve. once you are past that, the day-to-day is simpler.

the result

i now manage everything through flakes: my shell, my neovim config, my desktop packages, my ci pipelines. if a machine dies, i am back to a working environment in minutes, not hours. that alone is worth the upfront cost.