Wishes for the Future
(This is a long post. In the words of Blaise Pascal, “I have made this longer than usual because I have not had time to make it shorter.”)
I see the Nix project to have passed a critical moment. I think the Nix project has made great strides in solving some very hard problems, but my fear is that due to mismanagement, Nix will not succeed. In this post, I hope to share my perspective on what a better future for declarative, reproducible builds could look like, but sadly, I don’t think it involves Nix as it exists today. It’s hard to know what the future holds, and I am certain I do not hold the solutions to the problems that exist with Nix. However, I feel it would be a shame for the progress to be lost.
As background, on 2024-04-21, a group of concerned contributors and community members published an open letter to the NixOS foundation detailing Eelco Dolstra’s ill effects on the Nix project’s governance. On 2024-04-26, Eelco published a blog post that has caused many package maintainers to leave, including me. While I don’t have direct experience with the problems in the letter, I very much trust the folks who signed the letter. I am disappointed with how Eelco has chosen to handle the situation. I personally think this is a watershed moment for Nix, and not for the better. Such actions set the precedent for how an organization will act in the future, and given the power structure, there’s not much that can be done. In my mind, this endangers the health of Nixpkgs moving forward, and without healthy package maintenance, the Nix project is doomed. Consider this post a eulogy for a dream.
While the solution-that-is-Nix may evaporate, the problem it solves remains, at least for me. The rest of this blog post is my attempt at sketching what a suitable replacement would look like, in the hopes that it inspires someone to succeed where others have not. Perhaps a replacement is a fork, perhaps it is a wholly new project, perhaps it is the Nix project under better governance. I don’t know.
What I want to see
Since every person will look at Nix’s problem space with a different perspective, I wanted to share what I want out of a Nix-shaped solution. This is important to spell out because as you’ll see later in this post, a problem with Nix the project is its inability to communicate these core value propositions.
- Reproducible development environments. I want every machine that checks out my source code to use the same version of the tools used to build the software, without fuss.
- Consistency between local development and production. I want software artifacts that I build on my development machine to match what’s deployed in production.
- Building Docker or virtual machine images. I want to use the same solution that I’m using to managing dependencies to build Docker images and virtual machine images for me.
- An accessible and inclusive experience. This covers many things. Most important is having an “open, welcoming, diverse, inclusive, and healthy community” (to borrow from the Contributor Covenant). I feel strongly that this includes the onboarding experience of a tool. If a tool requires too much learning investment to get started, that excludes people from participating.
Nix delivered on the first three points quite well, but failed on the last point.
Alternatives
I personally don’t see any solution on the market that meets these goals. The two closest alternatives I see are Guix and Bazel. Guix is technically very related to Nix, but its association with the GNU project and its strict stance on non-free software runs completely counter to the goal of accessibility in my book. Bazel is better in regards to its community experience, but isn’t as well-suited to the technical use cases I outlined above. I could write a whole blog post on this (and perhaps one day I will), but this post is long enough as-is.
Mistakes were made
The open letter goes into great depth about specific leadership failures, but I’d like to explore what I see as second-order problems that stemmed from leadership failing to promote inclusivity. Since I am a relative newcomer to the Nix project, I’m not deeply familiar with all the development history, so there may be more nuance than what I’m presenting in this section. However, I am confident that as a whole, these issues demonstrate a failure to meet the need of accessibility.
- Complex installation. Installing Nix immediately involves a branching decision that is, in my opinion, not presented with enough information to make an adequate decision. This is made worse because changing the decision requires uninstalling Nix, which is entirely manual. This painpoint is so infamous that Determinate Systems made their own installer.
- Using a bespoke programming language. In my experience, this has stopped many of my colleagues from engaging with Nix at all. While I understand the technical reasons for the Nix language and personally find it quite an elegant solution, it is undeniably a hurdle for many.
- Not enough guidance on how to use the tool. The Nix project has traditionally taken the approach of providing core infrastructure and then expecting the user to glue together the parts themselves. Nix Flakes and the new CLI are attempts to give a more guided approach, but despite the relative stability of Flakes (as far as I can tell), it has yet to be marked stable. Ironically, this makes the installation even more complex. Beyond that, I’ve seen many people be shocked that you can a) use Nix without NixOS, b) use Nix to establish a per-project development environment, and c) use Nix to build Docker images or virtual machine images. Despite these being arguably core use cases, the docs do little to spell this out to potential users (or even existing ones!).
Wishlist
If you’ll indulge me, dear reader, I have some ideas for what I’d love to see from my ideal Nix replacement. The focus is on technical changes, but in my experience in the Go ecosystem, the incentives a tool creates will inform how the people using the tool interact.
To get the obvious out of the way, a suitable Nix replacement must have a reasonable Code of Conduct and a governance structure that avoids any one person having undue influence over the project. Adopting Contributor Covenant on Day 0 and being explicit about roles to avoid The Tyranny of Structurelessness seem like great places to start. I’m not very experienced in community management, so I’d leave it to more knowledgeable folks to solve those sorts of problems.
Next, a Nix replacement would ideally pick a different programming language for build definition. I think that despite their advantages, functional languages are not where most programmers are at, so that excludes the Nix language and Guile. I think Lua is worth examining: it does not add anything beyond a C compiler to the dependency tree of the interpreter and it has a proven track record of being easy to pick up. The only tweak required from stock Lua would be to implement the implicit string dependency trick that the Nix interpreter uses. Lua’s data model is close enough to what Nix already uses that I can’t foresee any hurdles. Using a more mainstream language would allow more people to contribute without a huge upfront time investment.
To make a Nix replacement ecosystem sustainable, I think the package repository needs to be decentralized, much like in Go. I’m imagining a very small “standard library” that has coreutils, compilers, and other programs that folks would expect on basically every Unix system. Then just about everything else should be made into a separate repository. I think Flakes got pretty close to this, but didn’t do enough to make it easy for folks to run binary caches outside nixpkgs.
Finally, there’s some missing quality of life issues that blocked widespread adoption in my opinion:
- Pinning a version of a package. Many people (myself included) have expressed frustration with how difficult it is to pin a version of a package. Decentralizing may actually go a decent way toward addressing this, since it would permit more fine-grained control over when software gets upgraded.
- Patching a package. This is frequently needed in enterprise contexts. The best practice that folks seem to converge to with Nix is to copy the derivation source code into their repository. This seems not ideal, but I don’t have a design for a better strategy.
- More turnkey language support. Projects like poetry2nix and gomod2nix should be part of a Nix replacement’s standard library. Solving these problems requires deep expertise of the build system and the programming language ecosystem: they aren’t really separable concerns.
What now?
So what are we left with? Eelco’s actions have erased my trust in the Nix project’s future. I am investigating how to remove my usage of Nix in infrastructure I operate. I want a better alternative, but one does not exist that meets my needs. The hacker in me wants to build one, but I know that I can’t do it by myself. And even if I could, I would not want to be trading one “Benevolent Dictator For Life” for another, especially if that dictator is me! Honestly, the only paths seem to lead backward, not forward.
But! I am personally not ready to give up on the promise on declarative, reproducible software. And I want to believe that there are others out there that feel the same way. I would love to build something better. If you feel the same, reach out to me. And maybe we’ll figure it out!