TIL: Symlinking NixOS Dotfiles

The standard answer to managing dotfiles on NixOS is home-manager. I’ve never used it, due to two aesthetic and one practical objection:

The approach I like is storing dotfiles in the same repository as flake.nix / configuration.nix and symlinking them in place.

The problem here is that NixOS seemingly doesn’t have a “native” way to say that /a/b/c should be a symlink to /c/d/e. Or has it?

If you search options for symlink, you’ll learn about environment.etc which allows you to configure symlinks, but only for things in /etc, not your ~/.config.

For the latter, you can use gnu stow or some other dotfile link manager, but the complexity of the problem of just managing symlinks doesn’t warrant yet another dependency. It’s fine to do this manually.

But wouldn’t it be nice if this framework for declarative configuration of your system allowed you to declaratively configure symlinks? Turns out this is possible, in roundabout way. Inaptly-named systemd-tmpfiles allows creating symlinks from a declarative config, and you can use NixOS to configure systemd-tmpfiles itself (thanks, Noobz!).

For example, if I want to symlink ~/dotfiles/git/config to .config/git/config:

{
  systemd.tmpfiles.rules = [
    "L+ /home/matklad/.config/git/config - - - - /home/matklad/dotfiles/git/config"
  ];
}

No opinion at this point how this compares to a bespoke script or something more purpose-built.