If you work on multiple machines or frequently set up new development environments, you know the pain of manually copying configuration files. chezmoi is a powerful dotfile manager that solves this problem elegantly, allowing you to manage your dotfiles securely across different machines.
What Are Dotfiles?
Dotfiles are configuration files in Unix-like systems that start with a dot (.), making them hidden by default. Common examples include:
.bashrc/.zshrc– Shell configuration.gitconfig– Git settings.vimrc/.config/nvim/init.lua– Editor configuration.ssh/config– SSH client configuration.tmux.conf– Terminal multiplexer settings
Why chezmoi?
While there are many dotfile managers (GNU Stow, yadm, dotbot), chezmoi stands out for several reasons:
- Security – Built-in support for secrets management with tools like 1Password, Bitwarden, or age encryption
- Templates – Use Go templates for machine-specific configurations
- Cross-platform – Works on Linux, macOS, and Windows
- Version control – Git integration out of the box
- Declarative – Define your desired state, chezmoi handles the rest
Installation
macOS (Homebrew)
brew install chezmoi
Linux (various methods)
# Using snap
sudo snap install chezmoi --classic
# Using curl (installs to ~/bin)
sh -c "$(curl -fsLS get.chezmoi.io)"
# Arch Linux
sudo pacman -S chezmoi
Windows
winget install twpayne.chezmoi
# or
choco install chezmoi
Getting Started
Initialize chezmoi
Create a new chezmoi repository:
chezmoi init
This creates a source directory at ~/.local/share/chezmoi where your dotfiles will be stored.
Add Your First Dotfile
chezmoi add ~/.zshrc
This copies .zshrc to the chezmoi source directory. The file is stored as dot_zshrc (chezmoi uses this naming convention for files starting with a dot).
Edit Files
Edit files in the source directory:
chezmoi edit ~/.zshrc
Or open the entire source directory in your editor:
chezmoi cd
Preview Changes
Before applying changes, see what would happen:
chezmoi diff
Apply Changes
Apply your dotfiles to your home directory:
chezmoi apply
Using Templates for Machine-Specific Config
One of chezmoi’s killer features is templating. Create machine-specific configurations using Go templates.
Example: Different Git Email per Machine
First, add your gitconfig as a template:
chezmoi add --template ~/.gitconfig
Then edit it:
chezmoi edit ~/.gitconfig
[user]
name = Kim Nis Neuhauss
{{- if eq .chezmoi.hostname "work-laptop" }}
email = kim@company.com
{{- else }}
email = kim@personal.com
{{- end }}
[core]
editor = nvim
Using chezmoi Data
Define custom data in ~/.config/chezmoi/chezmoi.toml:
[data]
name = "Kim Nis Neuhauss"
email = "kim@personal.com"
editor = "nvim"
Then use it in templates:
# In your .gitconfig.tmpl
[user]
name = {{ .name }}
email = {{ .email }}
Managing Secrets Securely
chezmoi integrates with popular secret managers to keep sensitive data out of your Git repository.
Using 1Password
# In your template
{{ onepasswordRead "op://Personal/SSH Key/private key" }}
Using Bitwarden
{{ (bitwarden "item" "github-token").login.password }}
Using age Encryption
For standalone encryption without external tools:
# Generate an age key
age-keygen -o ~/.config/chezmoi/key.txt
# Configure chezmoi to use it
chezmoi edit-config
encryption = "age"
[age]
identity = "~/.config/chezmoi/key.txt"
recipient = "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Add encrypted files:
chezmoi add --encrypt ~/.ssh/id_ed25519
Syncing Across Machines
Push to Git
chezmoi cd
git add .
git commit -m "Update dotfiles"
git push
Set Up a New Machine
On a fresh machine, initialize chezmoi with your repository:
chezmoi init --apply https://github.com/yourusername/dotfiles.git
The --apply flag immediately applies the dotfiles after cloning.
Keeping in Sync
Pull and apply updates:
chezmoi update
Or just preview what would change:
chezmoi update --dry-run
Advanced Features
Run Scripts
Execute scripts during apply. Create files like run_once_install-packages.sh:
#!/bin/bash
# run_once_install-packages.sh
# This runs only once per machine
if command -v brew &> /dev/null; then
brew install ripgrep fd fzf
fi
Script prefixes:
run_– Run every timerun_once_– Run only once (tracked by checksum)run_onchange_– Run when content changes
External Files
Fetch files from URLs:
# .chezmoiexternal.toml
[".oh-my-zsh"]
type = "archive"
url = "https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz"
exact = true
stripComponents = 1
Ignore Files per Machine
Create .chezmoiignore:
# Ignore on Linux
{{ if ne .chezmoi.os "linux" }}
.config/i3/
{{ end }}
# Ignore on work machines
{{ if eq .chezmoi.hostname "work-laptop" }}
.config/personal/
{{ end }}
My Recommended Workflow
- Start simple – Begin by adding your most important configs (shell, git, editor)
- Use templates sparingly – Only template files that actually differ between machines
- Encrypt secrets – Never commit plain-text secrets to Git
- Document your setup – Add a README to your dotfiles repo
- Test on fresh installs – Periodically test your setup in a VM or container
Common Commands Reference
| Command | Description |
|---|---|
chezmoi init | Initialize chezmoi |
chezmoi add <file> | Add a file to chezmoi |
chezmoi edit <file> | Edit a file in source |
chezmoi diff | Show pending changes |
chezmoi apply | Apply changes |
chezmoi update | Pull and apply from Git |
chezmoi cd | Open source directory |
chezmoi data | Show template data |
chezmoi doctor | Check for problems |
Conclusion
chezmoi transforms dotfile management from a tedious chore into a streamlined workflow. With features like templating, secret management, and cross-platform support, it’s the ideal tool for developers and sysadmins who work across multiple machines.
Start small, add your configs incrementally, and you’ll never have to manually copy dotfiles again.