Using NixOS as an stateless workstation

Posted on June 2, 2019

Last week1 I changed back to an old2 Samsung laptop, and installed NixOS on it.

After using NixOS on another laptop for around two years, I wanted verify how reproducible was my desktop environment, and how far does NixOS actually can go on recreating my whole OS from my configuration files and personal data. I gravitated towards NixOS after trying (and failing) to create an script that would imperatively install and configure my whole OS using apt-get. When I found a GNU/Linux distribution that was built on top of the idea of declaratively specifying the whole OS I was automatically convinced3.

I was impressed. Even though I’ve been experiencing the benefits of Nix isolation daily, I always felt skeptical that something would be missing, because the devil is always on the details. But the result was much better than expected!

There were only 2 missing configurations:

  1. tap-to-click on the touchpad wasn’t enabled by default;
  2. the default theme from the gnome-terminal is “Black on white” instead of “White on black”.

That’s all.

I haven’t checked if I can configure those in NixOS GNOME module, but I guess both are scriptable and could be set in a fictional run.

This makes me really happy, actually. More happy than I anticipated.

Having such a powerful declarative OS makes me feel like my data is the really important stuff (as it should be), and I can interact with it on any workstation. All I need is an internet connection and a few hours to download everything. It feels like my physical workstation and the installed OS are serving me and my data, instead of me feeling as hostage to the specific OS configuration at the moment. Having a few backup copies of everything important extends such peacefulness.

After this positive experience with recreating my OS from simple Nix expressions, I started to wonder how far I could go with this, and started considering other areas of improvements:

First run on a fresh NixOS installation

Right now the initial setup relies on non-declarative manual tasks, like decrypting some credentials, or manually downloading this git repository with specific configurations before that one.

I wonder what some areas of improvements are on this topic, and if investing on it is worth it (both time-wise and happiness-wise).


Right now I’m using the Spacemacs, which is a community package curation and configuration on top of Emacs.

Spacemacs does support the notion of layers, which you can declaratively specify and let Spacemacs do the rest.

However this solution isn’t nearly as robust as Nix: being purely functional, Nix does describe everything required to build a derivation, and knows how to do so. Spacemacs it closer to more traditional package managers: even though the layers list is declarative, the installation is still very much imperative. I’ve had trouble with Spacemacs not behaving the same on different computers, both with identical configurations, only brought to convergence back again after a git clean -fdx inside ~/.emacs.d/.

The ideal solution would be managing Emacs packages with Nix itself. After a quick search I did found that there is support for Emacs packages in Nix. So far I was only aware of Guix support for Emacs packages.

This isn’t a trivial change because Spacemacs does include extra curation and configuration on top of Emacs packages. I’m not sure the best way to improve this right now.


I’m using myrepos to manage all my git repositories, and the general rule I apply is to add any repository specific configuration in myrepos’ checkout phase:

# sample ~/.mrconfig file snippet
checkout =
  git clone guix
  cd guix/
  git config

This way when I clone this repo again the email sending is already pre-configured.

This works well enough, but the solution is too imperative, and my checkout phases tend to become brittle over time if not enough care is taken.

GNU Stow

For my home profile and personal configuration I already have a few dozens of symlinks that I manage manually. This has worked so far, but the solution is sometimes fragile and not declarative at all. I wonder if something like GNU Stow can help me simplify this.


I’m really satisfied with NixOS, and I intend to keep using it. If what I’ve said interests you, maybe try tinkering with the Nix package manager (not the whole NixOS) on your current distribution (it can live alongside any other package manager).

If you have experience with declarative Emacs package managements, GNU Stow or any similar tool, etc., I’d like some tips. If you don’t have any experience at all, I’d still love to hear from you.

  1. “Last week” as of the start of this writing, so around the end of May 2019. 

  2. I was using a 32GB RAM, i7 and 250GB SSD Samsung laptop. The switch was back to a 8GB RAM, i5 and 500GB HDD Dell laptop. The biggest difference I noticed was on faster memory, both RAM availability and the disk speed, but I had 250GB less local storage space. 

  3. The declarative configuration aspect is something that I now completely take for granted, and wouldn’t consider using something which isn’t declarative. A good metric to show this is me realising that I can’t pinpoint the moment when I decided to switch to NixOS. It’s like I had a distant past when this wasn’t true.