Why this matters
You do not need NixOS to get declarative dotfiles. Standalone home-manager runs on Arch, uses the Nix you already have, and manages only your $HOME. Omarchy and pacman keep owning the system. This is the lowest-risk way to start living in Nix daily, and everything you write here moves unchanged to NixOS later.
Concept
What home-manager is
A set of modules evaluated with lib.evalModules (see The module system), plus an activation script. The modules produce one derivation: a directory of files that should exist in your home. Activation symlinks them into place and installs packages into a profile. Nothing is copied; your ~/.config/fish/config.fish becomes a symlink into /nix/store.
The flake
Three inputs: nixpkgs, home-manager, and follows so both use the same nixpkgs. The lock file pins both. Unpinned home-manager against a different nixpkgs is the classic source of eval errors.
{
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
home-manager = {
url = "github:nix-community/home-manager";
inputs.nixpkgs.follows = "nixpkgs";
};
};
outputs = { nixpkgs, home-manager, ... }:
let
system = "x86_64-linux";
pkgs = nixpkgs.legacyPackages.${system};
in
{
homeConfigurations."dawit@laptop" = home-manager.lib.homeManagerConfiguration {
inherit pkgs;
modules = [ ./home.nix ];
};
};
}Verify: home-manager.lib.homeManagerConfiguration takes pkgs, modules, and optionally extraSpecialArgs. Confirm at https://nix-community.github.io/home-manager/#sec-flakes-standalone.
The attribute name "user@host" matters. home-manager switch --flake . tries homeConfigurations."$USER@$(hostname)" first, then "$USER". Verify: home-manager switch --help after install.
The first home.nix
{ pkgs, ... }:
{
home.username = "dawit";
home.homeDirectory = "/home/dawit";
home.stateVersion = "25.05";
programs.home-manager.enable = true;
home.packages = [
pkgs.ripgrep
pkgs.fd
];
}programs.home-manager.enable puts the home-manager command itself into your profile, so you do not depend on nix run after the first switch.
home.stateVersion
Not a version to update. It records which release's defaults you started with, so later home-manager releases can keep old behaviour for options whose defaults changed. Set it once, leave it. Changing it does not upgrade anything; nix flake update does.
Bootstrapping
The command is run once, from the directory containing the flake. It downloads home-manager and nixpkgs; on a 700 KB/s line that is minutes, not seconds.
nix run home-manager/master -- switch --flake .Afterwards, plain home-manager switch --flake . works because the command is now in your profile.
What it touches
~/.nix-profileis already a symlink to~/.local/state/nix/profiles/profile. Home-manager installs its package set into that profile as onehome-manager-pathentry.- Managed files become symlinks:
~/.config/git/config -> /nix/store/...-home-manager-files/.config/git/config. - A generation link under
~/.local/state/nix/profiles/home-managerand a GC root under~/.local/state/home-manager/gcroots/. Verify:ls ~/.local/state/nix/profiles/after the first switch. - Session variables land in
~/.nix-profile/etc/profile.d/hm-session-vars.sh. Your login shell must source it. The fish module does this whenprograms.fish.enable = true. Verify:grep hm-session ~/.config/fish/config.fishafter enabling.
Generations and rollback
Every switch is a new generation. Old ones stay until garbage collection.
home-manager generationsPrints one line per generation with its store path. To roll back, run that generation's activation script directly:
/nix/store/<hash>-home-manager-generation/activateVerify: there is no home-manager rollback subcommand in the version you install; check home-manager --help.
Coexisting with pacman
- PATH order decides who wins. On this machine
~/.nix-profile/binis already ahead of/usr/bin, so a Nixfishorneovimshadows the pacman one. Check withtype -a nvim. - Keep the login shell as
/usr/bin/fishfrom pacman. A store path is not in/etc/shells, andchshto a path that changes every update is fragile. Let home-manager manage the config, pacman the binary. - GUI apps from Nix on Arch need no special handling for Wayland, but icons and
.desktopfiles only appear in Walker if~/.nix-profile/shareis onXDG_DATA_DIRS.hm-session-vars.shadds it.
Try it
- Confirm home-manager is packaged in your pinned nixpkgs. No download beyond nixpkgs itself:
nix eval --raw nixpkgs#home-manager.version0-unstable-2026-08-06- Look at the profile home-manager will join:
ls -la ~/.nix-profile ~/.local/state/nix/profiles/lrwxrwxrwx 1 dave dave 44 Jun 16 14:38 /home/dave/.nix-profile -> /home/dave/.local/state/nix/profiles/profile
/home/dave/.local/state/nix/profiles/:
lrwxrwxrwx 1 dave dave 14 Sep 25 11:11 profile -> profile-1-link
lrwxrwxrwx 1 dave dave 51 Sep 25 11:11 profile-1-link -> /nix/store/5mcaq7843v0ixswhgbjdh6y9f2srk9wh-profile- Parse the two files above before you fetch anything:
nix-instantiate --parse flake.nix >/dev/null && nix-instantiate --parse home.nix >/dev/null && echo okokExercise
Create ~/dev/home/ with the flake and home.nix above. Run git init && git add . and nix flake check --no-build. Do not switch yet. Explain in one sentence why git add was necessary.
Solution
mkdir -p ~/dev/home && cd ~/dev/home
# write flake.nix and home.nix
git init
git add flake.nix home.nix
nix flake check --no-buildThe check fetches home-manager and writes flake.lock. Add that too.
Flakes only see files tracked by git. Without git add, ./home.nix does not exist from the flake's point of view and you get path '/nix/store/...-source/home.nix' does not exist. See Inputs and the lock file.
Trap
The first switch fails with a message like:
Existing file '/home/dawit/.config/fish/config.fish' is in the way of '/nix/store/...-home-manager-files/.config/fish/config.fish'
Please do one of the following:
- Move or remove the above files and try again.
- In standalone mode, use 'home-manager switch -b backup' to back up files automatically.Home-manager refuses to overwrite a file it did not create. That is a feature. Do not pass -b blindly; chezmoi still manages that file. Decide per file: either port it to a home-manager option or stop managing it with chezmoi. Migrate from chezmoi covers the order. Verify: exact wording differs between versions, and with -b an existing backup produces "would be clobbered by backing up".