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.

The usual way
brew install bun
brew install alejandra
# ...months of commands, remembered by no one
The Nix way
packages = [
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.

Mutation vs Convergence
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.