enuno

chezmoi - Dotfiles Manager

- [Reference](https://www.chezmoi.io/reference/)

enuno 12 3 Updated 4mo ago

Resources

1
GitHub

Install

npx skillscat add enuno/claude-command-and-control/skills-templates-chezmoi

Install via the SkillsCat registry.

SKILL.md

chezmoi - Dotfiles Manager

Manage your dotfiles across multiple machines, securely.

Quick Reference

Installation

# macOS
brew install chezmoi

# Linux (snap)
snap install chezmoi --classic

# Linux (binary)
sh -c "$(curl -fsLS get.chezmoi.io)"

# Windows
winget install twpayne.chezmoi
# or
choco install chezmoi

Essential Commands

Command Description
chezmoi init Initialize chezmoi on new machine
chezmoi add ~/.bashrc Add file to source state
chezmoi edit ~/.bashrc Edit file in source state
chezmoi diff Preview changes before apply
chezmoi apply Apply changes to home directory
chezmoi update Pull from remote and apply
chezmoi cd Open shell in source directory
chezmoi doctor Check for common problems

Quick Start (New Machine)

# Initialize from GitHub (combines clone + apply)
chezmoi init --apply $GITHUB_USERNAME

# Or with full URL
chezmoi init --apply https://github.com/username/dotfiles.git

Daily Workflow

# Add new dotfile
chezmoi add ~/.config/starship.toml

# Edit and apply in one command
chezmoi edit --apply ~/.bashrc

# Check what would change
chezmoi diff

# Apply all changes
chezmoi apply -v

# Push changes (in source directory)
chezmoi cd
git add . && git commit -m "Update dotfiles" && git push

Source State Attributes

File Prefixes

Prefix Effect Example
dot_ Adds . to filename dot_bashrc.bashrc
private_ Mode 0600 (user only) private_dot_ssh/
executable_ Mode +x executable_dot_local/bin/script
readonly_ Mode -w readonly_dot_config
encrypted_ Encrypted file encrypted_private_dot_ssh/id_rsa
empty_ Keep empty file empty_dot_gitkeep
create_ Create only if missing create_dot_config
modify_ Modify existing file modify_dot_bashrc
remove_ Remove from target remove_dot_old_config
symlink_ Create symlink symlink_dot_vimrc
exact_ Remove unlisted items exact_dot_config/

Template Suffix

Add .tmpl to process as Go template:

dot_gitconfig.tmpl
private_dot_ssh/config.tmpl

Script Prefixes

Prefix Behavior
run_ Run every apply
run_once_ Run once (tracks hash)
run_onchange_ Run when content changes
before_ Run before file updates
after_ Run after file updates

Example: run_once_before_install-packages.sh.tmpl

Templates

Basic Syntax

{{ .chezmoi.hostname }}
{{ .chezmoi.os }}
{{ .chezmoi.arch }}
{{ .chezmoi.username }}
{{ .chezmoi.homeDir }}

Conditionals

{{ if eq .chezmoi.os "darwin" }}
# macOS specific
export HOMEBREW_PREFIX="/opt/homebrew"
{{ else if eq .chezmoi.os "linux" }}
# Linux specific
export PATH="$HOME/.local/bin:$PATH"
{{ end }}

Complex Conditions

{{ if and (eq .chezmoi.os "linux") (eq .chezmoi.hostname "workstation") }}
# Work machine Linux config
{{ end }}

Whitespace Control

{{- .variable -}}  # Trim both sides
{{- .variable }}   # Trim left only
{{ .variable -}}   # Trim right only

View Available Data

chezmoi data

Test Templates

chezmoi execute-template '{{ .chezmoi.hostname }}'
chezmoi cat ~/.bashrc  # Preview rendered template

Password Manager Integration

1Password

{{ onepassword "item-name" }}
{{ onepasswordRead "op://vault/item/field" }}
{{ onepasswordDocument "document-uuid" }}
{{ onepasswordDetailsFields "item-name" }}

Modes: account (default), connect, service (for CI/CD)

Bitwarden

{{ bitwarden "item" "example.com" }}
{{ (bitwarden "item" "example.com").login.password }}
{{ bitwardenFields "item" "example.com" }}
{{ bitwardenAttachment "id_rsa" "item-uuid" }}
{{ bitwardenSecrets "secret-id" }}
{{ rbw "item-name" }}

Auto-unlock (chezmoi.toml):

[bitwarden]
    unlock = "auto"

pass (Unix Password Manager)

{{ pass "path/to/secret" }}
{{ passFields "path/to/secret" }}

gopass

{{ gopass "path/to/secret" }}

LastPass

{{ lastpass "item-id" }}

AWS Secrets Manager

{{ awsSecretsManager "secret-name" }}

Azure Key Vault

{{ azureKeyVault "secret-name" }}

Vault (HashiCorp)

{{ vault "secret/path" }}

Encryption

Setup with age (Recommended)

# Generate key
age-keygen -o ~/.config/chezmoi/key.txt

# Configure chezmoi.toml
[age]
    identity = "~/.config/chezmoi/key.txt"
    recipient = "age1..."

Setup with GPG

# Configure chezmoi.toml
[gpg]
    recipient = "your-gpg-key-id"

Add Encrypted Files

chezmoi add --encrypt ~/.ssh/id_rsa
chezmoi add --encrypt ~/.config/secrets.yaml

Encrypted files use encrypted_ prefix automatically.

Configuration File

Location: ~/.config/chezmoi/chezmoi.toml

Common Settings

# Source directory (default: ~/.local/share/chezmoi)
sourceDir = "~/.dotfiles"

# Default editor
[edit]
    command = "nvim"

# Git auto-commit and push
[git]
    autoCommit = true
    autoPush = true

# Diff settings
[diff]
    pager = "delta"

# Merge tool
[merge]
    command = "nvim"
    args = ["-d", "{{ .Destination }}", "{{ .Source }}", "{{ .Target }}"]

# age encryption
[age]
    identity = "~/.config/chezmoi/key.txt"
    recipient = "age1xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"

Machine-Specific Data

[data]
    email = "user@example.com"
    name = "Your Name"

[data.work]
    proxy = "http://proxy.work.com:8080"

Access in templates: {{ .email }}, {{ .work.proxy }}

Machine-Specific Configuration

Config Template (.chezmoi.toml.tmpl)

Create in source root for interactive setup:

[data]
    email = {{ promptString "email" | quote }}
    name = {{ promptString "name" | quote }}
{{- if eq .chezmoi.hostname "work-laptop" }}
    work = true
{{- end }}

Data Files (.chezmoidata.yaml)

packages:
  common:
    - git
    - tmux
    - neovim
  work:
    - docker
    - kubectl

Access: {{ .packages.common }}

Conditional File Inclusion (.chezmoiignore)

# Ignore on non-Linux
{{ if ne .chezmoi.os "linux" }}
.config/i3/
.xinitrc
{{ end }}

# Ignore work config on personal machines
{{ if not .work }}
.config/work/
{{ end }}

Scripts

Install Packages (run_onchange)

#!/bin/bash
# run_onchange_install-packages.sh.tmpl

{{ if eq .chezmoi.os "darwin" -}}
brew bundle --file=/dev/stdin <<EOF
{{ range .packages.common -}}
brew "{{ . }}"
{{ end -}}
EOF
{{ else if eq .chezmoi.os "linux" -}}
sudo apt-get update
sudo apt-get install -y {{ range .packages.common }}{{ . }} {{ end }}
{{ end -}}

One-Time Setup (run_once)

#!/bin/bash
# run_once_before_setup-directories.sh

mkdir -p ~/.local/bin
mkdir -p ~/.config
mkdir -p ~/.cache

Trigger on File Change

#!/bin/bash
# run_onchange_reload-shell.sh.tmpl
# Hash: {{ include "dot_bashrc.tmpl" | sha256sum }}

source ~/.bashrc

Common Patterns

GitHub SSH Keys

# dot_ssh/authorized_keys.tmpl
{{ range gitHubKeys "username" }}
{{ . }}
{{ end }}

Include Partial Templates

# .chezmoitemplates/git-config
[user]
    name = {{ .name }}
    email = {{ .email }}

# dot_gitconfig.tmpl
{{ template "git-config" . }}

[core]
    editor = nvim

External Files

# .chezmoiexternal.yaml
".vim/autoload/plug.vim":
    type: file
    url: "https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim"
    refreshPeriod: 168h

".oh-my-zsh":
    type: archive
    url: "https://github.com/ohmyzsh/ohmyzsh/archive/master.tar.gz"
    stripComponents: 1

All Commands (56 Total)

Core: add, apply, archive, cat, cd, data, diff, edit, forget, init, manage, managed, merge, re-add, remove, source-path, status, target-path, unmanage, unmanaged, update, verify

Config: cat-config, dump-config, edit-config, edit-config-template

Encryption: age, age-keygen, decrypt, edit-encrypted, encrypt, secret

Utility: chattr, completion, destroy, doctor, dump, generate, git, help, ignored, import, license, list, merge-all, purge, ssh, state, upgrade

Container: docker

Troubleshooting

Check for Issues

chezmoi doctor

Verbose Output

chezmoi apply -v
chezmoi diff -v

Dry Run

chezmoi apply -n  # Preview without changes

Debug Templates

chezmoi execute-template < file.tmpl
chezmoi cat ~/.config/file  # Show rendered content

Reset State

chezmoi state delete-bucket --bucket=scriptState  # Re-run scripts
chezmoi forget ~/.config/file  # Stop managing file

When to Use This Skill

  • Setting up dotfiles management across machines
  • Creating machine-specific configurations with templates
  • Encrypting sensitive dotfiles (SSH keys, API tokens)
  • Integrating password managers with dotfiles
  • Writing install/setup scripts for new machines
  • Syncing dotfiles via Git repository
  • Managing complex multi-machine configurations

Resources