05 February 2025 at 11:40 (UTC)
Last month, I temporarily migrated from Arch Linux to NixOS, a declarative Linux
distribution built around the Nix package manager. The Nix package manager and NixOS
were primary focal points of Eelco Dolstra's PhD dissertation at the Utrecht University
College in Utrecht, Netherlands.
Before migrating to NixOS, I read numerous portions of Dr. Dolstra's dissertation to get into the headspace of his design philosophy
with regard to the Nix package manager, and NixOS as a whole. It should be noted that following an open letter from the Nix community,
Dr. Dolstra stepped down from the NixOS
Foundation Board. I do not believe that this decision will cause the project to deviate from its original design goals, however.
I chose to install NixOS using the minimal (non-GUI) ISO image, as it is about 63% smaller than the graphical ISO image whilst allowing
for the same functionality. Though short, the NixOS installation guide worked as-written.
A notable deviation I made was instead opting to create a swap partition instead of a swap file. As the NixOS installation guide
has one label partitions, if one chooses to use a swap partition instead of a swap file they can use swaplabel -L NIXSWAP /dev/sdX
. The
installation guide was sufficient to create a functional system without any further deviations.
After about a few hours of configuration (now lost to time), I was able to mirror the functionality of my previously existing Arch Linux
system.
Overall, I like the declarative nature of NixOS, as well as the simplistic syntax of the Nix language.
If you have little-to-no programming experience, the Nix language is quick to grasp and easy to implement.
As configurations are often purpose-built to fulfill a user's particular needs, I will avoid delving into the specifics of my own, instead
choosing to focus on overarching themes related to the Nix package manager and NixOS.
Starting with the Nix package manager: do not believe the tagline "Search more than 120,000 packages." Yes, the packages do exist in
the repository... but it's a stretch. When clicking on a package one can view a list of package maintainers, and many of the packages
listed are orphans. At the time of writing, the Arch User Repository (AUR) lists 11,527 of its 89,973 packages
as orphaned (~12.8%). One of the niceties of Arch Linux is that the AUR is separate from the main repositories (Core, Extra, and Multilib).
At time of writing, the Core, Extra, and Multilib repositories account for 14,706 packages, wherein only 348 are orphaned (~2.37%). 336 of
those 348 packages are not flagged as out-of-date, meaning that there are 12 unmaintained packages with available updates in the
Arch Linux main repositories at time of writing. That's ~0.082% of the main repositories. Unfortunately, obtaining a statistical figure
for Nix's package repository is difficult, as the data is not provided directly. I have a strong suspicion that Nix suffers from a
figure of orphaned packages higher than ~12.8% and especially 0.082%.
That being said, however, Nix package sources are much more elegant than PKGBUILD due to the beauty of the Nix language. Though I am
not in favor of dynamically typed languages, the Nix language makes the NixOS configuration experience quite pleasant. As a former user
of xmonad (I've moved to Wayland and Hyprland!), the Nix language does an excellent job abstracting challenges
that purely functional programming often poses for new programmers, as in the case of Haskell.
As mentioned before, Nix and NixOS are declarative, whereas a Linux distribution like Arch Linux would be considered imperative.
When installing Arch Linux, everything installed onto the system is purposefully selected by the user during the pacstrap
stage of
installation. If instead of base one wanted to individually install its dependencies and
elect to exclude some of them, it is possible to do so. With NixOS, however, the installation process brings in some common utilities that may
not be declaratively included in one's configuration.nix
. Though I'm sure this is done to simplify the installation process, it can potentially
lead to confusion about when and where software was installed. For example, though a bootloader may not have been declaratively included
in one's configuration.nix
, systemd-boot will be automatically installed to make up for
this discrepancy in favor of creating a functioning installation. There are advantages and disadvantages to this approach, however, I
felt that it was out of the spirit of NixOS to enable software that had not been declaratively installed by the user. As such, I prefer
Arch Linux's approach of imperatively installing all utilities and software onto the system, even if it results in issues due to
user error or simple forgetfulness on installation.
Lastly, the final and primary advantage of NixOS is that it works, and it's reproduceable. Botching one's configuration, or even
accidentally deleting it (if system.copySystemConfiguration
is set to true
) is no big deal on NixOS. While rollbacks and
previous iterations of the system state take up more space, it's nice to have an extra layer of protection from incidents that
are usually major. Though NixOS requires more storage due to this design methodology, it's not as bad as one might think. With
frequent garbage collection, especially after multiple configuration changes that result in a stable configuration, the impact
on system storage is rather negligible. Overall, this design methodology makes NixOS rather enticing for both developers and
tinkerers.
So, why did I return to Arch Linux? Though I am a developer and can appreciate the elimination of Python's venv
and a
myriad of dependency conflicts, there's one large counter-argument to NixOS's existence in the modern landscape: containers.
Often optimized and tailored for specific workflows, containers serve a similar purpose as the original goal of Nix: reproducible
software deployment. When inquiring with my roommate about their workflow at a tech company, they had never even heard of NixOS,
stating that their company does development work within containerized environments. I then had to ask myself: why do I need
NixOS, and unfortunately I came up short of a worthy answer. Though NixOS has its merits, none of them fill voids within my
current workflow. That being said, however, it was a pleasure to give NixOS a try, and I enjoyed reading portions of Dr. Dolstra's
dissertation. I wholeheartedly believe that the problems he aimed to solve with Nix and NixOS existed, and still exist to lesser
extents. As someone more familiar with containers and virtual machines, however, I do not personally have a reason to continue
with Nix and NixOS. If Nix and NixOS's propositions cater toward your workflow, however, I strongly recommend giving it a try.