escaping dependency hell with nix

system

the problem

every developer has been there. you clone a repo, run the build, and get a wall of errors because your version of python is wrong, or a native library is missing, or the tool expects glibc 2.31 but you have 2.35.

dependency hell is not a nix problem. it's the default state of software development without nix.

what nix actually is

nix is three things: a package manager, a build system, and a language. the key insight is reproducibility by construction.

every package in nix is identified by a cryptographic hash of all its inputs — source code, compiler version, build flags, dependencies. if two builds have the same hash, they produce identical output. bit-for-bit.

{
  description = "my rust project";
  inputs.nixpkgs.url = "github:nixos/nixpkgs/nixos-unstable";
  outputs = { self, nixpkgs }: {
    devShells.default = nixpkgs.legacyPackages.x86_64-linux.mkShell {
      packages = with nixpkgs.legacyPackages.x86_64-linux; [
        rustc cargo clippy rust-analyzer
      ];
    };
  };
}

the nix store

everything nix installs goes into /nix/store. each package lives in its own directory named by its hash:

/nix/store/abc123-rustc-1.75.0/bin/rustc
/nix/store/def456-rustc-1.76.0/bin/rustc

two versions of the same tool coexist without conflict. no symlink gymnastics. no virtualenvs. no pyenv, rbenv, nvm, or any other version manager.

nix flakes

flakes are nix's answer to lockfiles. flake.lock pins every input to an exact commit hash. share the flake, get identical environments across every machine.

the learning curve

i won't lie: nix is hard to learn. the language is lazy and functional in ways that surprise you. error messages are cryptic. the documentation is scattered.

but after six months, i deleted homebrew, asdf, and docker from my machines. my development environments boot in seconds and work identically on my laptop and my CI server.

Command Palette

Search for a command to run...