A personal Nix flake managing system (NixOS) and user
(Home Manager) configuration across several hosts and platforms: NixOS
desktops/laptops, an aarch64 NixOS VM, macOS (aarch64-darwin), and Pop!_OS as
a Home-Manager-only target.
There is no application code here — every change is configuration that gets evaluated by Nix and activated on a host.
- Overview
- Initial setup
- Installing Nix
- NixOS setup
- Home Manager (standalone)
- macOS setup
- Everyday commands
- Inspecting changes
- Services
- Application configuration
- License
Configuration is split into two output sets in flake.nix, keyed by host:
nixosConfigurations.<host>— full NixOS systems.homeConfigurations."mir@<host>"— standalone Home Manager (used on macOS and Pop!_OS, and on NixOS hosts too, since Home Manager is not imported as a NixOS module here).
The repo is expected to live at ~/dev/nix-config. The bin/rename-and-link.sh
helper backs up a system-generated file and replaces it with a symlink into this
repo, bringing it under version control.
These steps are common to every platform.
Generate a key on the new system so it can clone this repo from GitHub, then add the public key to your GitHub account.
ssh-keygen -t ed25519 -C "abcdef@gmail.com"
cat ~/.ssh/id_ed25519.pubgit may not be available yet, so pull it into a temporary nix shell for the
session instead of installing it.
nix shell --extra-experimental-features nix-command --extra-experimental-features flakes nixpkgs#git
git clone git@github.com:nazmir/nix-config.gitNixOS already ships with Nix. On non-NixOS systems (macOS, Pop!_OS) install it first:
# Installs upstream Nix (not the Determinate distribution) via the
# Determinate Systems installer.
curl -fsSL https://install.determinate.systems/nix | sh -s -- installBring the system-generated config files under repo control, then rebuild. The
rename-and-link.sh script backs up the source file (arg 1) and links it to the
target (arg 2).
Note: Don't rename the hardware config to a machine-specific name the way
configuration.nixis renamed — keep it ashardware-configuration.nix.
sudo ~/dev/nix-config/bin/rename-and-link.sh /etc/nixos/configuration.nix ~/dev/nix-config/nixos/hosts/pc/configuration-pc.nix
sudo ~/dev/nix-config/bin/rename-and-link.sh /etc/nixos/hardware-configuration.nix ~/dev/nix-config/nixos/hosts/pc/hardware-configuration.nix
sudo nixos-rebuild switch --flake $HOME/dev/nix-config/.#mir-nixos-pcUsed on every host (NixOS, macOS, Pop!_OS). Link the generated config into the repo before the first switch.
cd ~/dev/nix-config
# Initialize Home Manager; places a config at ~/.config/home-manager/home.nix
nix run home-manager/master -- init --switch
# Drop the generated flake and link our host file in its place
rm ~/.config/home-manager/flake.*
~/dev/nix-config/bin/rename-and-link.sh ~/.config/home-manager/home.nix ~/dev/nix-config/home-manager/hosts/home-nixos.nix
# Initial evaluation with flakes
home-manager switch --flake ~/dev/nix-config/.#mir@mir-nixos-pcmacOS (aarch64-darwin) follows the shared flow —
Initial setup, Installing Nix, and
Home Manager (standalone) — with the macOS-specific
notes below.
-
git comes from the Xcode Command Line Tools
xcode-select --install
-
Home Manager uses the macOS host file and flake target when you reach the Home Manager step:
~/dev/nix-config/bin/rename-and-link.sh ~/.config/home-manager/home.nix ~/dev/nix-config/home-manager/hosts/home-mac.nix home-manager switch --flake ~/dev/nix-config/.#mir@mir-m4pro-mbp
-
Set fish as the login shell — see Fish shell under Application configuration.
-
Ghostty — the nixpkgs
ghosttypackage is Linux-only, so the app itself is installed via Homebrew (declared inmacos/Brewfile, see below), while its configuration is managed declaratively by Home Manager inhome-manager/hosts/home-mac.nix. -
Non-Nix channels — on macOS this repo runs standalone Home Manager (no nix-darwin), so the flake only manages Nix packages. Homebrew, global
uvtools, and hand-downloaded apps are tracked separately undermacos/. After the Home Manager switch, run:# Homebrew formulae + casks (and uv tools) — adopts already-installed apps brew bundle install --file=~/dev/nix-config/macos/Brewfile # Global uv tools, if you skipped brew or want them brew-independent while read -r t; do [ -n "$t" ] && [ "${t#\#}" = "$t" ] && uv tool install "$t"; done \ < ~/dev/nix-config/macos/uv-tools.txt # Hand-downloaded / App Store apps — open the checklist and reinstall each open ~/dev/nix-config/macos/apps.md
See
macos/README.mdfor the full bootstrap order, how to re-snapshot state after installing new things, and when adopting nix-darwin becomes worthwhile.
The nh helper (installed via Home Manager) is the preferred entrypoint for
rebuilds.
nh os switch --ask # Ask for confirmation before applying
nh home switch --ask
#home-manager switch --flake '.#mir@mir-nixos-pc'
nh home switch -c mir@mir-nixos-pc ./
# Specify the flake explicitly:
nh os switch --ask ~/dev/nix-config/.#mir-nixos-thinkpad
# Use the current hostname with an explicit flake path:
nh os switch --ask ~/dev/nix-config/nix flake updatenh clean all # Clean OS and Home profiles
nh clean user # Clean user profilesClean a specific profile:
nix profile list
nh clean profile -a nixGL # nixGL is the profile name; -a asks for confirmationIf the nh helper isn't installed yet (e.g. a fresh install):
sudo nixos-rebuild switch --flake $HOME/dev/nix-config/.#mir-nixos-thinkpad
home-manager switch --flake $HOME/dev/nix-config/.#mir@mir-nixos-thinkpadBuild the result before switching, then diff it against the running system:
sudo nixos-rebuild build --flake $HOME/dev/nix-config/.#mir-nixos-thinkpadnvd diff /run/current-system/ ./result/
nvd diff $(ls -d1v /nix/var/nix/profiles/system-*-link|tail -n 2) # Compare after a switchnvd wraps nix store diff-closures with improved reporting. The underlying
command is:
nix store diff-closures $(ls -d1v /nix/var/nix/profiles/system-*-link|tail -n 2)sudo tailscale up -authkey tskey-auth-KEY # Get the key from the Tailscale consoleThe shell prompt uses starship, configured declaratively
in home-manager/common.nix — no manual setup step is required.
Fish is installed and configured for every host via home-manager/common.nix.
To make it the login shell:
-
On NixOS, set it declaratively in the system config (
users.users.<name>.shell = pkgs.fish). -
On non-NixOS systems (macOS, Pop!_OS), register and switch to the Home-Manager-provided fish:
sudo sh -c 'echo $HOME/.nix-profile/bin/fish >> /etc/shells' chsh -s $HOME/.nix-profile/bin/fish
Install Doom Emacs, then run doom doctor to check for issues. Back up an
existing ~/.emacs.d first:
mv ~/.emacs.d ~/.emacs.d.origLink the Doom configuration into the repo:
~/dev/nix-config/bin/rename-and-link.sh ~/.config/doom/ ~/dev/nix-config/.config/doom~/dev/nix-config/bin/rename-and-link ~/.config/sway/config ~/.config/sway/config~/dev/nix-config/bin/rename-and-link ~/.config/kitty/ ~/dev/nix-config/.config/kitty
# The result will be in the current folderReleased under the MIT License — free to use, copy, and adapt.