macOS configured declaratively with nix-darwin and home-manager. One repo, one command, and a fresh Mac ends up configured the same way every time.
Forked from kunchenguid/dotfiles.
- System - dark mode, key repeat, dock, Finder, trackpad
- Packages - Nix user packages, plus Homebrew for the few things it does better
- Shell - zsh with autosuggestions, syntax highlighting, and a starship prompt
- Editor - Neovim (rose-pine moon, clangd LSP for C/C++)
- Terminal - WezTerm (rose-pine moon, dimmed unfocused windows)
- Dev environments - direnv + nix-direnv, loading each project's own flake devShell
- Agents - Claude, Codex and opencode share one
AGENTS.md
Apple Silicon Mac. On Intel, set nixpkgs.hostPlatform = "x86_64-darwin"; in
configuration.nix.
git clone https://github.com/kienthuynh/dotfiles.git
cd dotfilesReview Adapting this repo first - in particular the Homebrew warning, which uninstalls undeclared packages on the first switch.
./bootstrap.shThis installs Determinate Nix, symlinks the repo to ~/.dotfiles, reconciles the
configured username with yours, and runs the first darwin-rebuild switch.
Edit the config, then apply:
./rebuild.shFiles under home/ are symlinked into place and take effect immediately, with no
rebuild. Everything else - package lists, macOS defaults, flake.nix - needs a
switch.
Validate without applying:
nix flake check --no-build
nix build .#darwinConfigurations.mac.system --dry-runRoll back a bad switch with sudo darwin-rebuild rollback.
| Path | Purpose |
|---|---|
flake.nix |
Entry point. Inputs, and the mac machine definition. |
configuration.nix |
System scope: macOS defaults, Homebrew. |
home.nix |
User scope: packages, shell, prompt, symlinks. |
home/ |
Config files symlinked into ~. Edited in place. |
bootstrap.sh |
Fresh-machine setup. Run once. |
rebuild.sh |
Apply changes. Run for every later change. |
MAINTENANCE.md |
Updates this config does not do for you. |
home.nix uses mkOutOfStoreSymlink so paths like ~/.config/nvim point
straight at home/.config/nvim in this repo, and the two cannot drift.
Warning
configuration.nix sets homebrew.onActivation.cleanup = "zap". Every switch
removes any Homebrew package or cask not listed in brews/casks. On a
machine with existing Homebrew installs, the first switch will uninstall them.
Read those lists and add anything you want to keep before running either script.
- Username -
bootstrap.shdetects it, or change the singleuserline inflake.nix. Everything else threads from that variable. - Host label -
"mac"appears inflake.nix,rebuild.sh, andbootstrap.sh. All three must match. - Git identity -
home.nixsets a name and email underprograms.git.settings.user. Change it, or your commits are authored as me. - Agent policy -
home/AGENTS.mdis installed for Claude, Codex and opencode. Fork without editing it and you inherit my instructions. - Agent CLIs -
claude-codeandcodexare casks. herdr's pane-state integration for each is installed out-of-band withherdr integration install <agent>, not by a switch. Claude'ssettings.jsonis declared here; Codex'sconfig.tomlis not, because Codex writes runtime state into it rather than keeping it separate. - herdr - a public homebrew-core formula. Remove it from
brewsif unused.
Public so it can be read, learned from, and forked. Pull requests are auto-closed and feature requests are not accepted; fork it and make it yours instead. Bug reports are welcome through GitHub Issues.
MIT No Attribution. See LICENSE.