If a friend asked me over coffee what Nix is, I would start the same way most people do: it’s a package manager. The interesting part is everything after the “but”.
A package manager, but
Unlike apt or brew, Nix doesn’t mutate the machine one install at a time. You describe the environment in a file, and Nix makes the machine match it. There is no trail of half-remembered terminal commands to reconstruct later.
brew install bunbrew install alejandra# ...months of commands, remembered by no onepackages = [ pkgs.bun pkgs.alejandra];The shell commands record what happened. The Nix file says what should be there. That distinction did not mean much to me until I had to rebuild a machine.
Why mutation causes trouble
Systems drift when we keep editing them in place. An install here and a quick fix there eventually produce a machine whose state exists only on disk and in someone’s memory.
Nix takes a different approach. Builds go into immutable store paths, and the system switches between those paths atomically. If I want a different result, I change the declaration and build again.
flowchart LR subgraph imperative [Mutating in place] A[install] --> B[tweak] --> C[hotfix] --> D[snowflake machine] end subgraph declarative [Declaring and converging] E[declaration] --> F[build] --> G[immutable store path] --> H[atomic switch] end
Why Nix is still fringe
Nix still feels oddly obscure for a tool that has been around this long. The learning curve is a large part of that. I also keep seeing other tools rediscover ideas that Nix has treated as normal for years, which makes me think wider adoption is mostly a matter of time.
The harder part is choosing a structure
When I recommend Nix, I warn people about the learning cliff first. You have to learn the language and get used to describing a result instead of writing a sequence of commands.
That is only the first difficulty. The next one is deciding how to organize your own configuration. Nix lets you create modules and options almost however you like, but the ecosystem cannot tell you which structure will suit you six months later.
The source code gives you a declarative system, and version locks make builds predictable. Neither one chooses the architecture for you. I only found a structure I liked after using my configuration long enough to notice which parts kept getting in my way.