TIL: Symlinking NixOS Dotfiles

matklad News

Summary

A developer shares a technique for symlinking dotfiles on NixOS using systemd-tmpfiles, without relying on home-manager or additional tools.

<header> <h1>TIL: Symlinking NixOS Dotfiles</h1> <time class="meta" datetime="2026-05-21">May 21, 2026</time> </header> <p>The standard answer to managing dotfiles on NixOS is <a href="https://github.com/nix-community/home-manager">home-manager</a>. I’ve never used it, due to two aesthetic and one practical objection:</p> <ul> <li> I avoid dependencies, especially in nix, which rivals Python in the number of approaches to dependency management. </li> <li> home-manager installs packages for the current user only, which makes sense on non-NixOS systems. But on a single-user desktop system, I prefer having just one set of packages. </li> <li> Having a source of truth for dotfiles be in nix store requires rebuilding your system to change config, which gets in the way of Emacs-style direct tinkering. </li> </ul> <p>The approach I like is storing dotfiles in the same repository as <code>flake.nix</code> / <code>configuration.nix</code> and symlinking them in place.</p> <p>The problem here is that NixOS seemingly doesn’t have a “native” way to say that <code>/a/b/c</code> should be a symlink to <code>/c/d/e</code>. Or has it?</p> <p>If you <a href="https://search.nixos.org/options?query=symlink">search options</a> for <code>symlink</code>, you’ll learn about <a href="https://search.nixos.org/options?query=environment.etc#show=option%253Aenvironment.etc"><code>environment.etc</code></a> which allows you to configure symlinks, but only for things in <code>/etc</code>, not your <code>~/.config</code>.</p> <p>For the latter, you can use <a href="https://www.gnu.org/software/stow/">gnu stow</a> or some other dotfile link manager, but the complexity of the problem of <em>just</em> managing symlinks doesn’t warrant yet another dependency. It’s fine to do <a href="https://github.com/matklad/config/blob/346afb44f0cc50a04b8e7008ab389a90a1dfdd0f/xtool/src/autostart.rs#L75-L105">this manually</a>.</p> <p>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 <a href="https://www.man7.org/linux/man-pages/man8/systemd-tmpfiles.8.html">systemd-tmpfiles</a> allows creating symlinks from a declarative config, and you can use NixOS to <a href="https://search.nixos.org/options?channel=25.11&amp;query=systemd.tmpfiles.rules">configure</a> <code>systemd-tmpfiles</code> itself (thanks, <a href="https://discourse.nixos.org/t/managing-config-files-why-not-use-mkoutofstoresymlink-for-everything/77643/21">Noobz</a>!).</p> <p>For example, if I want to symlink <code>~/dotfiles/git/config</code> to <code>.config/git/config</code>:</p> <figure class="code-block"> <pre><code><span class="line">{</span> <span class="line"> systemd.tmpfiles.<span class="hl-attr">rules</span> = [</span> <span class="line"> <span class="hl-string">&quot;L+ /home/matklad/.config/git/config - - - - /home/matklad/dotfiles/git/config&quot;</span></span> <span class="line"> ];</span> <span class="line">}</span></code></pre> </figure> <p>No opinion at this point how this compares to a bespoke script or <a href="https://github.com/feel-co/smfh">something more purpose-built</a>.</p>
Original Article
View Cached Full Text

Cached at: 05/22/26, 08:51 AM

# TIL: Symlinking NixOS Dotfiles Source: [https://matklad.github.io/2026/05/21/symlinking-nixos-dotfiles.html](https://matklad.github.io/2026/05/21/symlinking-nixos-dotfiles.html) May 21, 2026The standard answer to managing dotfiles on NixOS is[home\-manager](https://github.com/nix-community/home-manager)\. I’ve never used it, due to two aesthetic and one practical objection: - I avoid dependencies, especially in nix, which rivals Python in the number of approaches to dependency management\. - home\-manager installs packages for the current user only, which makes sense on non\-NixOS systems\. But on a single\-user desktop system, I prefer having just one set of packages\. - Having a source of truth for dotfiles be in nix store requires rebuilding your system to change config, which gets in the way of Emacs\-style direct tinkering\. 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](https://search.nixos.org/options?query=symlink)for`symlink`, you’ll learn about[`environment\.etc`](https://search.nixos.org/options?query=environment.etc#show=option%253Aenvironment.etc)which allows you to configure symlinks, but only for things in`/etc`, not your`~/\.config`\. For the latter, you can use[gnu stow](https://www.gnu.org/software/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](https://github.com/matklad/config/blob/346afb44f0cc50a04b8e7008ab389a90a1dfdd0f/xtool/src/autostart.rs#L75-L105)\. 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](https://www.man7.org/linux/man-pages/man8/systemd-tmpfiles.8.html)allows creating symlinks from a declarative config, and you can use NixOS to[configure](https://search.nixos.org/options?channel=25.11&query=systemd.tmpfiles.rules)`systemd\-tmpfiles`itself \(thanks,[Noobz](https://discourse.nixos.org/t/managing-config-files-why-not-use-mkoutofstoresymlink-for-everything/77643/21)\!\)\. 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](https://github.com/feel-co/smfh)\.

Similar Articles

How I like to install NixOS (declaratively)

Michael Stapelberg

A guide on declaratively installing NixOS over the network using tools like nixos-anywhere, with an emphasis on managing configuration files under version control.

My Nix Config Is Intimate

Lobsters Hottest

The author shares their pride in a comprehensive Nix configuration that manages all their machines efficiently, while explaining the personal and security reasons for keeping it private.

Nix needs relocatable binaries

Lobsters Hottest

The article identifies the problem that Nix binaries are not relocatable, causing hash changes and recompilation when the store prefix changes, and proposes using relative paths with $ORIGIN in RUNPATH to achieve relocatability without invalidating caches.

Build-time systemd schedule

Lobsters Hottest

The article explores using NixOS to inspect and manage systemd schedules at build time for self-hosted services, enhancing runtime checks.

NNN Stack: NixOS, Niri, Noctalia

Lobsters Hottest

The NNN Stack combines NixOS, Niri compositor, and Noctalia shell to create a declarative, scrollable, and reproducible desktop environment, inviting users to contribute their dotfiles.