The Stages of Nix Usage

<< Back

"I think I'll try using Nix for that"

As an unenthusiastic macOS user, I thought it might be possible to reduce my overall annoyance with it by using a tool like Nix instead of homebrew to manage the installation of coding type software. Since I build some software that I use everyday from source, using homebrew for managing those dependencies is a house of cards. Think complex software dynamically linked to libraries homebrew changes on a whim.

At the time, what I knew about nix was that it:

  • was a tool similar to apt for managing software and dependencies
  • could manage different versions of the same dependency
  • that it had its own lisp influenced scripting language

Deciding how to Nix

You start to get the sense that this Nix path you have chosen will not be easy. You have read your third blog post about how someone uses Nix. They are all different.

You thought reading a few blog posts would help you "get the hang of it". At this point, you seem to know less about what "it" is than when you first started.

Do I need a home-manager? Why do so many people have them? What are Flakes? Are they good? Should I use them?

As these questions swirl around, you realize learning Nix is not going to involve afternoon tea and a tutorial written by a smart and friendly person. In fact, as you search the Internet, you are starting to think you may need to cobble together a working knowledge of complex software via not-quite-up-to-date manuals and blog and news group posts. How can people use computers this way? Did they ever? Is this what people spent their time doing in the 1990's?

You might be asking at this point: is there an O'Reilly book for Nix? Can I just read that? The answer is: no.

Actually Learning Nix

While there is no O'Reilly book, you can search the internet for ways others have learned Nix. These generally tend to include:

I opted for reading the PhD thesis first thinking it would be a bit too dense, and that I could quickly cross it off the list. Fortunately, that wasn't the case at all. If you have read this far, odds are the thesis will describe a problem you deal with just about everyday that you likely did not know you had: packaging and installing software on different computers. The thesis sets about outlining an ideal solution to almost all of the problems posed by the current approaches to doing this. It sets up all these problems so we get to feel a catharsis as it knocks them down. We get to see the nuisances that stole our productivity and our afternoons vanquished by Nix, the hero of the story.

Nix in the Real World

You now are someone who knows how this Nix thing works. You get that it is doing a lot of sophisticated manipulation of symbolic links. You know it makes installing software a determinate process. You are sold, think it is awesome, and are ready to do something with this new found information.

Not so fast… Remember reading all those blog posts where everyone was showing off their own little hobby kits of Nix commands? Why do some people use nix develop and some nix shell? What is the difference?

The short answer to these kinds of questions is that some blog posts and/or people have embraced a newer, more experimental set of nix tooling. Nix Flake based tooling like nix develop represents the less reliable, harder to use, nix tooling of the future. Since Flake based tools are less mature and meant to embody some higher ideal of Nix usage of which you may only be dimly aware, it will take you longer to figure out what the hell is going on when these tools inevitably misbehave. On the other hand, you will be doing the community a solid by not asking for help with commands that no one is interested in using anymore.

All Your Dev Tools are Installed Wrong

At this point, you may have installed some non-trivial system software via Nix and/or Flakes. Well, that does it, right? Time to return to business as usual. Now let's install a version manager for Ruby or Python since that is what we do.

Unfortunately, that is only what we did in the dark days before we learned of Nix. Although, I am pretty sure there is a way to install tools like Poetry or rbenv via Nix, once you begin to consider what they do and that one of the primary use cases of Nix is per project dev environments, you begin to suspect you maybe missing something.

At first glance, this seems like some Nix geekery you may be able to safely ignore, but when you stop to consider what a perfectly setup dev environment offers, it begins to feel like one last avenue to be explored.

For example, consider using Emacs with a Ruby on Rails project. In order for Emacs to perform much of the razzle dazzle to do autocompletion, syntax checking, and in-editor REPL's it is easiest if it can rely on the path to executables like rails, rubocop, and rspec not having some weird prefix. Ideally, when it calls rails it is calling the rails for your project and not some other version of rails installed on your system.

I was able to get this all working by creating a Flake for the Rails project I was using. The trick to getting Emacs to work seamlessly with the project dev tools was, for me, to have a per project version of Emacs. In other words: one that was installed by the Flake for the project. Now, if I start Emacs from the project root, it has access to all the correct dev tools.

As simple as all that sounded, I think it is worth noting here that much of my previous experience with docker has led me in the opposite direction from this type of simplicity. Want to a open Ruby console for your docker configured web app? Better startup and build a container!? Ick. It never occurred to me what a waste of resources this was until I started using Nix to manage my dev environments.

Choosing a Practical Project

As I was alluding to, I chose to do my first practical work with Nix by setting up a Flake for an existing Ruby on Rails project. This project in particular was quite old and, as I mentioned, I wanted to use Emacs.

These two facts lead to doing some non-trivial work to get a working Flake for the dev environment. The tasks include:

  • Working with and understanding Nix Overlays. This is required for getting a custom built, per project version of Emacs
  • Negotiating with Nix to install an unsupported, insecure version of OpenSSL to support Ruby 2.7.

You can read about the Emacs Overlay here. I had to use my own variation of the hack described here to allow the Flake to install the old version of OpenSSL.

Was It Worth the Time?

For me, yes. I spend too much time doing dev work to have sloppily installed tools. After tossing the baggage that comes with docker and homebrew, my system is less cluttered and more responsive and more things just work.

Nix is a powerful tool that solves a lot of problems and I don't remember a time when such a thing was available to anyone with the time and inclination to learn it. There is no question that it is only for a certain type of nerd to use right now. But I have to wonder what might happen if it continues to mature at the current rate or if someone were to package it up in such a way that more people could use it.

Emacs 29.4 (Org mode 9.6.15)