Replace home-manager
home-manager is a basic system for managing a user environment using Nix. It allows setting declarative user envs.
For a nixos user includes me, home-manager may already introduced at the same time as the config created, for managing user-spec configs. But it has really poor maintainence and code quality, and it does produced few bugs several months I use it. And I do considered removing it but seems there's no a better solution exist.
Things changed when I saw this post. TLDR:
- Use
nix profile
mechanism instead ofhome.packages
. User-spec package management solved. - Use
nix run
andnix app (flake)
mechanism for deploying user-spec software configs. This could be conveniently migrate from existing home-manager profile.
The blog above doesn't gave a detail implementation for referencing, which we'll discuss here.
Before start,
Follow this post you could finally get:
- rm
home-manager
- User specific software config switch timecost reducing, significantly.
- use home-manager as nixos module will require priviledge when trying change user settings, and consume same eval time as entire nixos config, which about 20s. Time cost reduced to
~4s
after this.
- use home-manager as nixos module will require priviledge when trying change user settings, and consume same eval time as entire nixos config, which about 20s. Time cost reduced to
- Better maintainence for config. If ur powerful enough.
What we'll lost
- No more home-manager. Things may not be better.
- Difficulties for calling OS config option in user specific config. In home-manager with nixosModule installation (standalone install has no this function as well btw) you generally do this by calling
osConfig
. - slate-symlink cleaning. Which could be easily solved by writting a simple script.
Prerequisites
- A Nix Flake, with a working nixosConfiguration.
- (optional) A home-manager config (either standalone or nixosModule installation)
- Want, to get rid of the home-manager.
- About 3 hours or days.
"Difference between user-specific packages/config and global's: they were stored under user home.
You can always start from install user specific package
Collect Configs (Optional)
If you already have a deployed home-manager configuration, which linked things to your $HOME/.config
directory, you may want to use this script to collect them all.
This will collect all symlink real paths into the ./target directory. Please note that you will still need to manually replace the /nix/store/xxhash-name strings in each file.
Here’s an example of what it collected for me:
Mapping target path & real file
We need to automatically build an attrset from the tree above. e.g.
for further manipulating. To implement this a recursive read and update could be introduced:
This will structure the attribute set according to the directory structure. It also provides a mechanism for using variables, such as pkgs.hello
, in the configuration. To do this, simply add the suffix .nix
to the file name and wrap the file content with a Nix string.
e.g.
will evaluated to:
Make a new dir in whatever place of your config repo. Place default.nix
in and you could copy target/*
, which above mentioned, or your $HOME/.config
if u don't use home-manager, into this directory. See structure or maybe a more elegant way.
This will read the entire dir and output a text:
Finally we need a nix app
for deploying these.
While config changed just run nix run
and all will be set.
More easily. Add following to flake toplevel
and userPkgs.nix
Trace by git.
while first deploy, run nix profile install .#userPkgs
.
while changed, run nix profile upgrade <index>
which index seen from nix profile list
NOTICE that if using root on tmpfs, ~/.nix-profile
may not exsit at startup if home on tmpfs, which causes packages not loaded to env. Adding a link for solving this.
You may need to pay attention to the behavior when garbage collection (GC) is executed, as discussed in the mentioned article.