Cross-device dotfiles management with chezmoi.
New machine:
sh -c "$(curl -fsLS get.chezmoi.io)" -- init --apply alexcarpenterPrompts: Name, Email
Existing machine:
chezmoi update.zshrc- Shell config, aliases, PATH.gitconfig- Git identity (templated), safe push defaultskarabiner.json- Key remappingsettings.json- VS Code theme & fontsBrewfile- Packages (JetBrains Mono, ZSH plugins, etc.)
Never edit dotfiles directly — changes get lost.
❌ Don't: nano ~/.zshrc, vim ~/.config/karabiner/karabiner.json
✅ Do: chezmoi edit ~/.zshrc
chezmoi edit ~/.zshrcOpens in $EDITOR (VS Code by default). Auto-applies on save.
chezmoi diff # See what changed
chezmoi cat ~/.zshrc # View rendered filechezmoi cd && git pushchezmoi updateDone! All machines identical.
MacBook:
chezmoi edit ~/.zshrc
# Add: alias blog="cd ~/Sites/blog"
chezmoi cd && git pushiMac:
chezmoi update
chezmoi cat ~/.zshrc # See new aliasAny machine:
chezmoi edit ~/.config/karabiner/karabiner.json
chezmoi cd && git pushOther machines:
chezmoi update| Task | Command |
|---|---|
| Edit dotfile | chezmoi edit ~/.zshrc |
| See changes | chezmoi diff |
| View file | chezmoi cat ~/.zshrc |
| Push | chezmoi cd && git push |
| Pull & apply | chezmoi update |
| Add new file | chezmoi add ~/.config/app/config |
| History | chezmoi cd && git log --oneline |
| Undo | cd ~/.local/share/chezmoi && git reset --hard HEAD |
export PATH="$HOME/.local/bin:$PATH"Add to .zshrc permanently with chezmoi edit ~/.zshrc
chezmoi apply # Force reapply
exec zsh # Restart shellchezmoi apply # Restore from sourcechezmoi cd && git pull --rebase
chezmoi applychezmoi diff # See what would change
chezmoi update # Then applySource directory: ~/.local/share/chezmoi/
Repository files (with dot_ prefix):
dot_zshrc→~/.zshrcdot_gitconfig.tmpl→~/.gitconfig(templated)dot_config/karabiner/karabiner.json→~/.config/karabiner/karabiner.jsonLibrary/Application\ Support/Code/User/dot_settings.json→~/Library/Application\ Support/Code/User/settings.jsondot_Brewfile→~/Brewfile
Files ending in .tmpl use Go templates:
{{ .user.name }}- Your name (from setup){{ .user.email }}- Your email{{ .chezmoi.os }}- darwin, linux, etc. (conditional sections){{ .chezmoi.hostname }}- Machine name (work vs personal)
Example (.gitconfig.tmpl):
[user]
name = {{ .user.name }}
email = {{ .user.email }}
{{ if eq .chezmoi.os "darwin" }}
[credential]
helper = osxkeychain
{{ end }}First run saves to ~/.config/chezmoi/chezmoi.toml:
[data.user]
name = "Alex Carpenter"
email = "im.alexcarpenter@gmail.com"
[data.machine]
hostname = "Alexs-Mac-mini"Git config not rendering correctly:
chezmoi cat ~/.gitconfig # Check rendered outputNew machine has wrong email:
chezmoi init # Re-run setup promptsPush blocked:
chezmoi cd && git push
# If fails: check GitHub auth, SSH keysDevices synced: MacBook, iMac, Work Laptop
Core files: .zshrc, .gitconfig, karabiner.json, VS Code settings, Brewfile