Nix Configuration

Nix Configuration

Nix facilitates declarative Linux systems, user dotfiles, and development environments.

Over the past couple months I have transitioned most of my computing to Nix and NixOS for inter-machine consistency, reproducibility, and program availability. It was an unfortunately steep climb and easily a project-level effort, but now that I’m here and comfortable, I couldn’t be happier with my return on investment.

Nix?

If you’re not familiar with Nix but are in the software dev world, think of Nix as “infrastructure as code” but for the individual machine; rather than infrastructure, the Nix ecosystem can manage Linux system configuration as code, package management as code, dotfiles as code, development environments as code, and so much more. Powering all these use-cases are the largest and freshest repo of packages, robust rollback capabilities, and a purely functional language for consistent inputs and outputs.

If you’re interested in learning more, I’d point you to No Boilerplate’s great NixOS summary video: Everything Everywhere All at Once.

If you want to try things out, I’d recommend following @Evertras/simple-homemanager to push you out of information paralysis, even if you just follow the first couple steps.

Nix!

For those who are familiar, here are the highlights of what I’ve done so far:

  • I’m running NixOS on my main machines at home, I’m running NixOS inside of WSL at work, and I install nix on top of other non-NixOS distros like on my Steam Deck
  • My configuration is defined as a flake, mostly just for ease-of-use
  • Home Manager is used to configure my user environment (including dotfiles) and I heavily prioritize the options it provides to keep my config as OS-agnostic as reasonable
  • I manage secrets and other sensitive values in a separate, private repo referenced as an external flake input
  • I wrote a recursive import system to reduce boilerplate and automatically namespace all my config snippets into their own enable options that are settable per-system (myHome.dev.git.enable = true;)
  • On my WSL work machine, I manage a small set of Windows program config via a Home Manager activation script I wrote, which copies Nix output to the native Windows filesystem
  • I’m using nh for a consistent and pretty CLI experience
  • I’m using Nix flakes and dev shells to manage project-specific development environments, including in shared projects with non-Nix-using collaborators
  • I wrote about the levels of Home Manager integration here

Impressions

I’ve been really impressed in a number of areas:

  • Ease of multi-system management. All my systems are the same where I want them to be and different when it makes sense. Nix’s typed option system and priority-based overrides make per-system deviations trivial and with little compromise.
  • Consistent package management. Installing a package being config means no missing packages, no unmaintained “install all my programs” script, and no unexpected version differences between systems and OSs.
  • Version flexibility. My editor is installed from the rolling release branch to get the latest updates, but the rest of my programs are installed from the latest fixed release for stability. I also have a machine running the rolling release for the sake of new GPU driver support, but the user-space programs are still installed from the fixed release for consistency with my other systems. And when the next fixed release is out, I’ll switch to it with one line change and a restart.
  • Proper encapsulation. For example, I love direnv for development but I don’t need it installed in all environments. Not having it can be tricky though, as its configuration leaks into other programs; it requires a shell hook and (for me) some gitignore additions. With Nix, I just declare the needed shell and git snippets in my direnv config module, and when the module is enabled, those get magically merged into my greater shell and git config. When the module is disabled and direnv is not installed, the snippets are no where to be found.

The Nix world is obviously not without downsides and you will be painfully reminded of that when you first start to toy with it. The lack of documentation is hard, the unknown terminology is hard, and the fundamentally different approach to everything is hard.

I got through the first two out of pure stubbornness and thankfully now have the language comprehension and experience to manage. The final point will likely always be tricky, but the benefits I have gotten out of Nix have thus far been well worth blowing the strangeness budget out of the water. May I wish the same for you.


© 2025. All rights reserved.