How to get (in)to Nix: resources, tools, and personal experience.

Nix is known to be hard to learn, and the official documentation can be difficult to navigate. I’ve been playing around with it for two years, following a plethora of guides and blog posts to implement this and that. I don’t see myself as a Nix expert for anything, but I’ve gathered a lot of resources over time.

I won’t talk about “Why you should use Nix” as there are plenty of posts about it, and if you are here, you’re probably at least curious about it. In this post, I go over the different use cases I’ve looked at, and redirect the reader to relevant resources on the subject. Let’s not reinvent the wheel.

Disclaimer >

This is an opinionated guide referring to sometimes opinionated resources. Therefore, it probably won’t be representative of a ground-truth about Nix, but I’ll try to follow where (at least part of) the community goes.

Nix all the things!

General resources

The official documentation for Nix as often regarded as difficult to navigate, and sometimes too old. It is, however, a great way to familiarize with Nix’ core concepts, and the motivation behind it. I would definitely advise starting there.

Official

Nix’s official documentation is structured around three manuals, one for each application of Nix. These manuals should remain the reference about Nix. I advise readers to start by going through the first two before digging too far into Nix.

About Nix flakes >

Starting with Nix 2.4, Nix ships with flakes, a new way to pin Nixpkgs revisions and specify packages dependencies. It’s often considered as the future of Nix. Many resources now deem channels (the old way) deprecated, and advocate for new users to focus solely on flakes. I personally have migrated all my workflows to flakes, and would not go back.

However, flakes are still officially considered as experimental. The official documentation, especially the Nix and Nixpkgs Manual, is often criticized for the lack of resources on flakes and the fact it still uses channels everywhere. The reference for the nix command (in the Nix Manual) contains details about flakes and how they should be used. This is, AFAIK, the only official resource.

The official learning portal also has smaller guides for specific aspects of the environment, such as how to pin Nixpkgs, how to use Nix for developer environments or to build Docker images.

The official team also maintain useful tools:

Unofficial

Due to how rapidly the ecosystem evolves, the official documentation sometimes seems to lack content, features, and tools. The evergrowing community stepped in to fill the gaps. Here are the most interesting semi-official or fully community-driven resources.

Alongside these resources, the community also maintain useful tools for digging through Nix.

Then how to start?

Even with this list, reading through all of it would take a lot of time. If you just want to get familiar with the technology, you can focus on the following:

  1. Start with Determinate Systems’ Zero to Nix tutorial. Embrace flakes and the Nix 2.0 CLI, as it is taught in this series. Follow the links to other concepts if you’re curious, but skip anything mentioning channels for now, as (1) you probably won’t need it, and (2) it might conflict with stuff your read.

  2. Go over the Nix manual, especially the sections about the language syntax. Being able to understand the language is key for digging into it afterwards.

  3. Play around! Install Nix (if you didn’t already), and try installing a package, or writing a shell environment.

While I would still recommend reading through at least one of the resources I previously mentioned, you can also start with a specific objective, and learn Nix along the way. Therefore, you will find hereafter specific resources depending on your objective to “streamline” your learning.

Reproducible development environments

Probably one of the main use case for Nix is the creation of reproducible development environments. Let’s look at some situations where you could benefit from Nix.

These examples of misfortune are all caused by version mismatch, happening at different level in the tool chain. Some situations can be fixed, like the Python version, by adding other tools to the mix, but Nix offers a do-it-all solution.

If you are interested in reproducible development environments, have a look at the following resources:

The principles behind development environments can easily be extended to any kind of shell environments. For instance, RedNix (a NixOS-based distribution for penetration testing and security) provides devShells for different categories of security tools. This can be adapted to other use cases, as long as one of your activities requires having access to a set of packages and configurations in your shell. You can make it more permanent by looking at profiles.

While Nix can theoretically be installed on any Linux distribution (as well as on MacOS), users might be reluctant to install a daemon running in root to use it. There are community efforts to make nix portable and self-contained, but these are very niche projects.

About right management >

You need administrator rights to install Nix, as it requires mounting a dedicated volume at / for the nix store (/nix/store)—where derivations, sources, and binaries are stored—, and running a root daemon for multi-users installations. However, once it is done, every other operation can be done at user-level without particular rights.

Finally, you can have a look at devenv.sh, a do-it-all utility that aims at streamlining the entire DevOps process using Nix. It is especially geared towards novices, and does a lot of stuff to make Nix’s ecosystem more accessible. Therefore, I would recommend against using it, as it does a lot of abstraction that hides how Nix works. Furthermore, if you use flakes (which you should), a devenv.nix file in your project directory will not do much that you cannot do with your flake.nix if you know the syntax, such as shell environments, build recipes, and more. It remains a great tool if you do not want to learn about Nix, or for user service management in your environment.

Tidying your $HOME

Probably the second most important advantage to Nix’s ecosystem is its declarative package and configuration management system, via NixOS. However, it is impossible to enjoy (some of) the advantages of NixOS on other distributions.

Home-Manager is a community project to port NixOS’ philosophy to the user’s home directory and user services. Originally made by Robert Helgesson, the project has since been transferred to the nix-community GitHub organisation. The latter is a semi-official organization that works alongside the official NixOS team to maintain community projects and resources around the entire Nix ecosystem.

Home-Manager has its own “official” documentation, but it is quite sparse. Some of the resources that we have already covered address Home-Manager and its usage, but the following are specific to it.

Declarative System Configuration

Finally, NixOS is a Linux distribution based on Nix. The rationale behind NixOS is the same as Nix’: the package manager generates build output in the Nix store, and simlinks them to the filesystem. With NixOS, the same is applied to configuration files, eg. most of your /etc directory will be simlinks to /nix/store. To learn about NixOS, the best way remains to play with it. The official NixOS Manual and Zero-to-Nix’ dedicated page are great general resources on that regard, as mentioned above.

Now, NixOS is full of resources, and there are a lot of documentation and blogposts to enable this and that. I’ll give a list of use cases here, and let the reader select those that seem relevant.

My toolbox

I have developed a tendency to use Nix everywhere (which you will too!), but my main use case remains development environments. As I work on a lot of different projects, I use Nix and Direnv to instantiate environments dynamically when I enter a project’s directory, without having to install anything globally. I also use Nix to manage my dotfiles (via Home-Manager), and to deploy and manage Linux systems (via NixOS). A such, I write a lot of (ugly) Nix code, and I have a few tools that I use to make my life easier. Here is a non-exhaustive list of them.