Ahhhh, Nix/NixOS. The package manager/OS that I so desperately wanted to love.

I stuck with Nix for about six months. I even became a package maintainer.

In the end, I gave up for three reasons:

1. Documentation is really bad. It's often confusing, incomplete or just plain wrong. What drove me crazy is the extreme imprecision with which certain fundamental concepts are referred to. For example, "derivations" are among the basic building blocks of Nix's package management system, yet I counted at least three unrelated ways in which they're referred to within different parts of the documentation. There were also many times when the only way to solve routine problems was to get in contact with Nix's developers.

2. I never appreciated how much package management is intertwined with individual ecosystems' cultures until I tried using a "universal" package manager like Nix. Take Node packages. The norm is to install in a project's node_packages directory, and many packages rely on that idiom just to function (e.g., hardwired to import modules with that particular directory structure in mind). Nix attempts to translate each ecosystem's idioms into its own system by introducing many helper functions (all written in the Nix language, very few of which are documented) for each ecosystem. The problem is more fundamental than the fact that this approach is only partially successful and many packages remain subtly broken. The real problem is that there's no unified meta-approach or design language to rationalize how each ecosystem's idiosyncrasies are assimilated. The API's for each ecosystem's Nix helper functions are totally different. You end up as a "Nix Node package developer" just to do your job as a web developer, and then a "Nix Python package developer" just to add a Python package, and so on.

3. The developers don't seem to have any interest in solving these UX problems. They are quick to respond and welcoming people, but the impression I was left with is that they're mostly academics or just interested in whatever subsystem they're working on. For example, when I was working on Nix, the canonical mechanism for updating a single Node package in the Nix repository was to run a script that updated all (yes, all) Node packages in the repo. When I pointed out all the ways that this was an impractical approach, the response was that it's actually a good thing because that way the Node packages in the repo don't get get stale (!) This was one of a few examples I encountered where the devs didn't seem to be aware of how unusable Nix was in real world cases.

My mini-review is from the perspective of someone who was willing to put in the time to jump through all the hoops. I've left out obvious issues that would be a showstopper for many (e.g., obscurity of the Nix language, poor support on macOS). The issues that I've listed are "fit and finish" issues that at a glance may appear superficial, but having worked in the community for a while, I came to believe are more fundamental. They're about governance and what the community wants from the project. I don't believe that their goals are aligned with those of most devs who probably want a system that solves one of the biggest pains in tooling, package management.

It's a pity because Nix's design is really ingenious. Making a "functional" package manager in and of itself is a huge achievement. What I didn't appreciate when I started using Nix is how it normalizes the act of programming your package manager. It's like shifting from Heroku to CloudFront except with much worse docs. The idea is brilliant, the promise is there, but the team doesn't seem interested in turning the whole package from a project into a cohesive product.