Featured image of post Chezmoi: Elegant Dotfile Management Across Linux and Windows

Chezmoi: Elegant Dotfile Management Across Linux and Windows

How to securely and conveniently synchronize user configuration files across different operating systems using chezmoi, Go templates, and Git.

Managing configuration files (dotfiles) across multiple machines inevitably turns into chaos over time. A standard Git repository in your home directory quickly gets cluttered, symlinks often break on Windows, and storing secrets like API tokens or plain-text usernames publicly is extremely unsafe.

The solution to this problem is chezmoi — a modern, Go-based dotfile manager. It allows you to manage settings across Linux, WSL, and Windows securely and systematically.


🚀 Why Choose Chezmoi?

Unlike traditional symlink-based approaches, chezmoi stores target configurations in a dedicated directory (by default ~/.local/share/chezmoi) and applies changes to your live system only when explicitly instructed.

  • Cross-Platform: Works seamlessly on Unix-like systems, WSL, and Windows.
  • Go Template Support: Dynamically substitutes variables (such as username, hostname, or email) based on the target host.
  • Built-in Security: Native encryption support for sensitive data using age or GnuPG.
  • Automated Provisioning: Supports run_once_ scripts to install packages during initial system setup.

📦 Repository Layout and Structure

Here is an example structure of a chezmoi-managed dotfile repository:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
dotfiles/
├── .chezmoi.toml.tmpl                     # Chezmoi configuration template
├── .chezmoiignore                         # Files and directories to ignore
├── dot_bashrc                             # Becomes ~/.bashrc
├── dot_gitconfig.tmpl                     # Template for ~/.gitconfig with variables
├── private_dot_config/                    # Becomes ~/.config/
│   ├── helix/                             # Helix editor configuration
│   ├── starship/                          # Starship prompt setup
│   └── wezterm/                           # Cross-platform WezTerm terminal
├── run_once_after_10-base-packages.sh.tmpl   # Base CLI package installer (Linux/WSL)
└── run_once_after_20-windows-packages.ps1.tmpl # Package installer (Windows)
Naming Conventions

Prefixes in chezmoi filenames define their target attributes: dot_ transforms into a leading dot (.bashrc), private_ creates a restricted folder (chmod 700), and .tmpl enables the Go template engine.


⚡ Quickstart and Initialization

Linux / WSL

  1. Install the utility:

    1
    2
    
    sh -c "$(curl -fsLS get.chezmoi.io)" -- -b ~/.local/bin
    export PATH="$HOME/.local/bin:$PATH"
    
  2. Initialize from a GitHub repository:

    1
    
    chezmoi init --apply <your-username>
    

Windows

On Windows, the easiest way to install chezmoi is via the Scoop package manager:

1
2
3
4
5
6
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned -Force
iwr -useb get.scoop.sh | iex
scoop install main/chezmoi git gh

# Initialize configuration inside Git Bash:
chezmoi init --apply <your-username>

🔄 Daily Command Cheatsheet

CommandDescription
chezmoi edit ~/.bashrcOpen a file in your default editor.
chezmoi diffShow differences between repository state and $HOME.
chezmoi apply -vApply changes from source state to the living system.
chezmoi updatePull changes from Git repository and apply them immediately.
chezmoi add ~/.config/helix/Add a new directory under chezmoi tracking.
chezmoi cdNavigate into chezmoi’s local source directory.

📊 Leveraging Templates

Go templates allow you to maintain a single dot_gitconfig.tmpl across all your devices:

1
2
3
[user]
    name = {{ .name }}
    email = {{ .email }}

Variables are read from your personal .chezmoi.toml file or requested via interactive prompts during initialization.

Caution with Provisioning Scripts

Scripts prefixed with run_once_ execute automatically only once. Always verify generated script output prior to running using chezmoi execute-template < <file>.

On Windows systems, to prevent accidental execution of Bash scripts, it is recommended to apply changes using: chezmoi apply --exclude=scripts.


Built with Hugo
Theme Stack designed by Jimmy