Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I see the appeal of Nix, but if your package manager requires a 50 part how-to learn series...

At this point I don't really know if the juice is worth the squeeze.



I don't think of Nix as a package manager; I think of it like Make.

The problem with Make (other than the awful syntax!) is that it's not composable. For example, GCC has a Makefile, with an "install" rule; yet my C project's Makefile can't use that as a dependency; e.g.

    hello: hello.o installGCC
        gcc -o hello hello.o

    hello.o: hello.c installGCC
        gcc -c hello.c

    # Pseudocode to import the 'install' rule (renaming as installGCC), from the
    # Makefile in GCC's source (depends on gccSource to fetch it)
    @import: gccSource
        import(gcc-10.1.0/Makefile, install -> installGCC)

    gccSource:
        wget 'http://mirror.0xem.ma/gnu/gcc/gcc-10.1.0/gcc-10.1.0.tar.gz'
        tar xzf gcc-10.1.0.tar.gz
Nix solves that problem: we can write a rule (Nix calls them "derivations") which run wget/curl/git/whatever, and we can import files from the result.

Nixpkgs (a big collection of definitions for Nix) takes this to its logical conclusion: C programs not only depend on their source, but also on the compiler, the shell used to run the commands, etc. In turn, the compiler depends on its source, and a shell, and a compiler (if it's bootstrapped). The shell depends on its source, and a compiler, and a shell to run the commands, etc. The downloader (usually curl) depends on its source, and a compiler, and a shell, etc.

The recursion is cut-off by some "bootstrap binaries" (which the bootstrappable-builds project is trying to shrink even further http://bootstrappable.org )

With this "composability" problem solved, it turns out there's actually no need for "package managers" at all; or indeed for "installing" anything: each derivation just says what other derivations it depends on. Nix can act like a package manager if you want it to; e.g. its 'nix-env' command manages a "user profile" (a symlink at ~/.nix-profile, which point to the output of a derivation, which itself symlinks to the output of whatever derivations we want "installed"). NixOS works in a similar way, but with a system-wide /run/current-system symlink (plus a massive pile of options to configure things more easily).

Hence the slight complexity of Nix (in fact, most of the complexity is in the libraries, like Nixpkgs) lets us do away with build tools (Make, Ninja, Ant, etc.), language package managers (maven, pip, cargo, npm, cabal, etc.), OS package managers (apt, yum, etc.), configuration managers (chef, ansible, puppet, etc.). Nix's "binary cache" mechanism also lets us do away with binary formats like rpm, dpkg, wheel, jar, etc. in a transparent manner (e.g. we can still patch sources, override compiler flags, etc.; we just get a cache-miss)

Of course, that's the ideal. There's so much code written with Makefiles, pom.xml files, setup.py files, cargo.toml files, etc. that most Nix definitions just add those tools as dependencies, and let them do the building!


Thank you for that explanation. Nix does seem like it may be worth a closer look.




Consider applying for YC's Fall 2025 batch! Applications are open till Aug 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: