Managed with chezmoi. Supports five machine profiles:
| Profile | Machine |
|---|---|
mac |
Personal MacBook |
work-mac |
Work MacBook |
jackbot |
Home Linux server |
hetz |
Hetzner VPS |
linux-3090 |
Linux GPU machine |
cricket |
Linux server |
Mac:
brew install chezmoi
chezmoi init --apply tyler-kellerLinux (one line — the installer drops chezmoi in ~/.local/bin and chains straight into init):
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin" init --apply tyler-kellertyler-keller expands to https://github.com/tyler-keller/dotfiles. If the repo is
private, put the box's ssh key on GitHub first and use
init --apply git@github.com:tyler-keller/dotfiles.git instead.
Don't paste trailing # comments — zsh passes them as arguments (no
interactive_comments by default), and the installer forwards stray args to chezmoi.
Chezmoi will prompt once: Machine profile (mac/work-mac/jackbot/hetz/linux-3090). Pick the right one. The answer is stored and never asked again on this machine.
That's it. Your dotfiles are deployed.
The shared ~/.zshrc is applied to every box, so never put box-specific
shell config directly in it — chezmoi apply will clobber it. Instead, drop
anything unique to one machine (custom PATHs, per-host aliases, secrets, work
tooling) in ~/.zshrc.local. It's untracked, never chezmoi-managed, and
sourced last so it overrides anything above.
Migrating an existing box (one that already had a hand-rolled ~/.zshrc):
before the first chezmoi apply, back it up and diff it against the rendered
template so nothing custom is lost —
cp ~/.zshrc ~/.zshrc.pre-chezmoi
chezmoi apply # writes the shared ~/.zshrc
diff ~/.zshrc.pre-chezmoi ~/.zshrc # review what changed
# move any genuinely box-specific lines into ~/.zshrc.local, then:
rm ~/.zshrc.pre-chezmoichezmoi init --apply --source ~/Code/dotfilesOr if you've already run chezmoi init and just want to apply changes:
chezmoi apply| Task | Command |
|---|---|
| Pull latest and apply | chezmoi update |
| Preview what would change | chezmoi diff |
| Edit a managed file | chezmoi edit ~/.zshrc |
| Add a new dotfile | chezmoi add ~/.foo |
| Re-run install scripts | delete state with chezmoi state delete-bucket --bucket=scriptState then chezmoi apply |
After editing files in the source directory (~/Code/dotfiles), commit and push as you would any git repo. On other machines, chezmoi update pulls and applies.
- Add a row to the profile table above
- In
.chezmoi.toml.tmpl, add ais<Name>boolean if you need machine-specific behavior - Update
.chezmoiignoreif the machine should skip certain files - Update any
.tmplfiles that branch on profile - Install chezmoi on the new machine and run
chezmoi init --apply
| File | Target | Notes |
|---|---|---|
dot_zshrc.tmpl |
~/.zshrc |
p10k on Mac, philips theme + GPG on Linux |
dot_gitconfig.tmpl |
~/.gitconfig |
SSH signing on Mac, GPG key on Linux |
dot_zshenv |
~/.zshenv |
Linux only — adds ~/.local/bin to PATH |
dot_p10k.zsh |
~/.p10k.zsh |
Mac only |
dot_vimrc |
~/.vimrc |
All machines |
dot_zsh/worktree.zsh |
~/.zsh/worktree.zsh |
Git worktree helpers (wt new/rm/ls/cd) |
dot_zsh/et.zsh |
~/.zsh/et.zsh |
Personal Mac only — Eternal Terminal helpers |
dot_config/nvim/ |
~/.config/nvim/ |
LazyVim — all machines |
dot_config/git/ignore |
~/.config/git/ignore |
All machines |
dot_config/ghostty/config |
~/.config/ghostty/config |
Mac only — Challenger Deep theme |
dot_config/zellij/ |
~/.config/zellij/ |
Linux servers only |
dot_config/claude/statusline-command.sh |
~/.config/claude/statusline-command.sh |
jackbot + linux-3090 |
dot_local/share/swiftbar/dexcom.2m.py |
~/.local/share/swiftbar/dexcom.2m.py |
work-mac only |
Not chezmoi-managed (stored in repo for reference):
settings.json/keybindings.json— VS Code; manually copy to~/Library/Application Support/Code/User/chat-personalization-settings.txt— Claude AI personalization
run_once_install-nvim.sh and run_once_install-et.sh run automatically on chezmoi apply (once per machine). They're skipped on platforms where they don't apply (ET install is Linux-only, nvim install skipped on Mac since you likely use brew).
To re-run an install script after updating it, chezmoi detects the content change and re-runs automatically on next chezmoi apply.
If you set the wrong profile:
chezmoi state delete-bucket --bucket=persistentState
chezmoi init --apply