Discovering Nix

What is Nix?

I recently had the opportunity to play with Nix, which is a package manager and an OS based on this package manager. Nix is special in the sense that it claims to only make reproducible builds that can’t break the system. But how?

The package manager is “purely functional”, which means that the packages are built without side effects and then stored in the Nix store in their own folder. Each packet folder is final and will never be updated.

$ ls /nix/store

Any change in the package dependencies or inputs for a given packet will trigger a complete new build for it. This means that you can have multiples versions of every package. That’s also why you won’t break another package in your system by updating some dependencies. You get immutable builds in exchange for high disk usage for storing all versions of all the dependencies. You also get history and rollback for each packages thanks to this design.

Most packages are also built from source, including all their dependencies. No pre-built binaries, so everything should be built right for your system. But the first installation will take more time than with a classic package manager.

Using Nix

As a user, you get access to some parts of the nix store depending on what you install. If you only want to try some packages you can just run it as a one-off:

$ nix run "nixpkgs#bat"

This references the nixpkgs repository which is the official repository. But technically any Github repository can serve as a nix repository.

It has to be noted that I’m using the flakes experimental feature along with the unified CLI. This puts all commands under nix instead of having to use nix-env, nix-shell, nix-build

When I want to use a package long-term, I can install it in my profile, which basically only needs to put a symlink to the nix store.

$ nix profile install nixpkgs#bat
$ bat

Nix also has the nix develop command which allows you to enter a development environment from a local or remote definition. This means that you can enter an environment with pre-installed dependencies in your PATH (python, ansible, git…), environment variable definition, specific configuration… Creating your own development environment involves using Nix’s own functional language which has a steep learning curve but allows you to customize your builds.

I’m not really familiar with all of the Nix ecosystem yet, but I like the overall philosophy, and I can see the benefits of the development environment to synchronize a lot of dependencies between the devs (contrary to using a docker container just to run python or relying on a lot of version managers).

— Morgan