需要先装好 Nix 并克隆仓库到该路径;Homebrew cask 应用和 Claude Code 等自更新程序不在 Nix 管理内,需单独处理;应用配置需 sudo 执行 darwin-rebuild

sudo darwin-rebuild switch --flake ~/src/github.com/babarot/dotfilesREADME 未说明
用 Nix flake 声明两台 Mac 的完整开发环境,工具增删都只改一个文件
一套用 Nix 管理的个人 dotfiles 集合,涵盖 Neovim、终端等配置,方便在不同机器上快速复现一致的开发环境。
核心能力
- 用 nix-darwin 加 home-manager 统一声明 macOS 环境
- 每个工具一个文件,删文件即卸载全部相关配置
- 工具间按 Nix store 路径引用,删一个不破坏其他
- 用 is_human 区分人类与 AI agent 的 shell 行为
- flake.lock 锁定版本,新 Mac 可复现同样环境
容易踩的坑
暂无 release 数据(可能没有发版,或尚未同步)。
用户点评
登录用户的真实使用记录,可按版本和硬件筛选还没有人点评。第一个说出真实体验的人最有价值。
dotfiles
My macOS environment for two Macs, declared in one Nix flake (nix-darwin + home-manager).
- Terminal: Ghostty + Herdr, one workspace per git worktree for Claude Code and Codex
- Editor: Neovim
- Packages: Nix
Shell for humans and AI agents
AI agents (Claude Code, Codex, ...) now run more commands in this shell than I do, so the shell is plain by default and human UX is opt-in.
.zshenvdefinesis_human: true only when stdin/stdout are a TTY and no agent marker (CLAUDECODE,AI_AGENT, ...) is set- Agents get plain zsh: none of the human aliases (
cp -i,ls→ eza), no fzf-drivencd,EDITOR=trueandPAGER=cat, so nothing waits for input .zshrcreturns early unlessis_human; below that line come aliases, plugins, prompt, keybinds and setopts
Export AI_AGENT=1 to force the agent side.
One file, one lifecycle
What is added and removed together is installed and configured in one file under nix/home-manager/tools/ (or nix/hosts/<host>/ for one Mac), imported automatically: usually one tool, sometimes a tool with its companions or a set, like the Kubernetes tools below. Adding a tool is adding a file, and deleting the file is all it takes to remove it. Three properties make that safe:
- Cohesion: deleting a tool's file removes everything that was for it (package, aliases, variables, plugins), so nothing outlives the tool.
- Loose coupling: deleting a tool's file breaks nothing else. A tool used inside another's settings is referenced by its store path, not through PATH. In the example below, kubectx's picker keeps working after
fzf.nix, andfzfon PATH with it, is deleted. - Reproducibility: a new Mac gets the same thing. Everything is declared here and pinned by
flake.lock; what Nix cannot hold (self-updating apps through Homebrew casks, Claude Code) is declared as an exception.
A tool's settings sit next to its package, by who they are for: my.human for humans only, my.ai for agents only, my.env for both. The rules are in AGENTS.md, and how Nix makes the properties hold is in docs/concepts/dependencies.md.
# nix/hosts/PC-M-2025-026/kubernetes.set.nix (abridged)
# A set: the Kubernetes tools, added and removed together with this file
{ lib, pkgs, ... }:
let
# kubectx runs fzf for its picker, looking it up on PATH by name. This wraps
# kubectx so it finds fzf by its path in the Nix store instead: deleting
# fzf.nix takes fzf off PATH, but not away from kubectx.
kubectx = pkgs.symlinkJoin {
name = "kubectx-with-fzf";
paths = [ pkgs.kubectx ];
nativeBuildInputs = [ pkgs.makeWrapper ];
postBuild = ''
wrapProgram $out/bin/kubectx --suffix PATH : ${lib.makeBinPath [ pkgs.fzf ]}
'';
};
in
{
# Installed by this file, and uninstalled when it is deleted
home.packages = with pkgs; [
helmfile
kubectl
kubectx # the wrapped one above
kustomize
];
# For humans only: agents never get this abbreviation
my.human.plugins.zsh-abbr.init = ''
abbr --session --quiet k=kubectl
'';
}
Layout
flake.nix # one configuration per Mac
nix/
darwin.nix, macos.nix # system settings and macOS System Settings for every Mac
homebrew.nix # vendor apps installed by Homebrew casks
hosts/ # per-Mac packages, casks and App Store apps
home-manager/ # dotfile links, shell env, tool files in tools/
...
home/ # hand-written dotfiles, linked into ~ under the same names
.zshenv, .zshrc, .zsh/ # zsh
.config/ # linked to ~/.config as a whole
.claude/ # Claude Code user settings
bin/ # scripts still being shaped
skills/ # my own Agent Skills on trial
...
docs/ # guides, concepts and reference (see docs/README.md)
Apply changes
sudo darwin-rebuild switch --flake ~/src/github.com/babarot/dotfiles
Updating packages is in maintenance.md.
Docs
- Setting up a Mac
- Everything else (how things work, how to maintain them, why they are this way) is indexed in docs/