The itch
Dotfiles are where we think with our hands.
Home Manager makes user environments reproducible, which are immutable by default.
Then you want to tweak a terminal color, a window rule, a keybinding, or a simple program's configuration. That part should feel immediate.
The usual move
Leverage Home Manager modules.
Easy to start with. Immutable by default. Not ideal for tinkering around.
Alternative to modules
Place the config file in the nix store.
Simple. Reproducible. Portable. Also read-only by design.
The loop
Every tiny change becomes a rebuild.
That is fine for committed configuration, but it gets in the way while discovering what the configuration should be.
The hidden lever
Home Manager already has an escape hatch.
mkOutOfStoreSymlink points the managed file at your working copy instead of copying it into the Nix store.
The catch
It works, albeit being a leaky abstraction.
Each module starts carrying path math, and a hardcoded symlink'd config file. Hard to share. Not reproducible on different machines.
Dots
Make the boring part disappear.
One function at the call site. One module owns the immutability policy.
The contract
Three options are enough.
mutable chooses the mode. path says where the live checkout is. sourceRoot lets Dots compute the relative path.
Two modes
Same modules, different mood.
Configuration goes into the Nix store. Great for sharing, CI, rollback, and machines that should be pinned in place.
Configuration links to the working tree. Great for trying things quickly and committing once the shape feels right.
The ultimate combo
Dots plus wrappers for an easy win.
Forget about XDG configuration files and local state. Packages become self-contained, fully configured and easy to share.
Try it out!
Expose your wrappers in your flake.
The wrappers option is part of dots and can be used to easily access your custom packages.
The payoff
Mutable while exploring. Immutable when sharing. Still Home Manager.