I’ve been using NixOS recently on my laptop, because I know how great declarative configuration is from my experience deploying software on servers with tools like Kubernetes and Terraform. Along the way, I’ve had a few experiences with it that have left me impressed with how powerful a declarative approach to the configuration of my personal computers can be.
Declarative vs imperative
If you’ve used any electronic device that you can install software on, you are already aware of the imperative approach to device configuration.
If a piece of software doesn’t exist on your machine and you want it to, you run an installer or tell the package manager to install it:
apt-get install -y neovim
A problem with installing packages this way is that over time you may build a collection of software with incompatible versions of dependencies. You might want to upgrade all the software on your machine, but you don’t have any guarantee that the upgrade will succeed. And if you do break something, the only way to fix it might be to reinstall. You might even want to reinstall every couple years anyways to start fresh.
NixOS lets you define the configuration of your system declaratively. The
software you want to be installed on your system is listed (or enabled) in
a config file — configuration.nix — and after you add new software to
this file, you tell NixOS to rebuild your entire system by running
nixos-rebuild switch.
{ config, pkgs, ... }:
{
# ...
programs.thunderbird.enable = true;
programs.fish.enable = true;
users.defaultUserShell = pkgs.fish;
programs.neovim = {
enable = true;
defaultEditor = true;
};
# Allow unfree packages
nixpkgs.config.allowUnfree = true;
# List packages installed in system profile. To search, run:
# $ nix search wget
environment.systemPackages = with pkgs; [
# vim # Do not forget to add an editor to edit configuration.nix! The Nano editor is also installed by default.
wget
];
}
Every time you rebuild your system, Nix “evaluates”
all the packages you’ve chosen and their dependencies, and saves the output
— the build artifacts — in the Nix store. Usually, nix doesn’t need to build
the packages you’ve chosen and they can be downloaded directly from a Nix “cache
server”.
After download or build, the packages involved in the
active configuration have their binaries symlinked into a special directory included
in the PATH.
On my machine, this is /run/current-system/sw/, and /run/current-system/sw/bin/nvim
is a symlink to /nix/store/xz3jy2lzzzycq3dnavn7v1hyr598pyr9-neovim-0.11.5/bin/nvim,
for example. In fact, /run is mounted as a tmpfs that is setup when the machine boots
or the configuration is switched. Changing the configuration is an atomic operation
that can be reversed easily, including by rebooting and selecting an older configuration
from the GRUB startup menu. A NixOS system, including the installed packages
and system-wide configuration, is essentially itself a build artifact — the result of an
evaluation of your configuration.nix.
Package installation and system configuration happen in one place
There are a number of configuration options available in NixOS …





SpiralSynthModular, an old modular softsynth that left an impression on me
A real, physical, Doepfer A-100 modular synthesizer. (


