From chezmoi
Manage dotfiles with chezmoi - a cross-platform dotfile manager using a source-state model. Use when: (1) Working with chezmoi (2) Managing user-level configs outside of chezmoi that would be useful to bring into chezmoi
How this skill is triggered — by the user, by Claude, or both
Slash command
/chezmoi:chezmoiThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
chezmoi manages dotfiles using a **three-state model**: source (declared in `~/.local/share/chezmoi`), destination (current home directory), and target (computed desired state). Running `chezmoi apply` updates destination to match target.
chezmoi manages dotfiles using a three-state model: source (declared in ~/.local/share/chezmoi), destination (current home directory), and target (computed desired state). Running chezmoi apply updates destination to match target.
chezmoi init # Initialize source directory
chezmoi add ~/.bashrc # Add file to management
chezmoi edit ~/.bashrc # Edit source file
chezmoi diff # Preview changes
chezmoi apply # Apply changes to home directory
chezmoi apply -n -v # Dry run with verbose output
chezmoi cd # Enter source directory
chezmoi data # Show template variables
chezmoi doctor # Diagnose issues
chezmoi managed # List managed files
dot_, private_, executable_, .tmpl, etc.). See attributes reference..chezmoi* files control chezmoi behavior. See special files reference.Key principle: Only symlink files that are modified by external tools (package managers, plugin systems, app settings auto-writers). Everything else should use normal chezmoi copy workflow.
Ask: "Will something other than me edit this file?" If yes → symlink. If no → copy.
lazy-lock.json (updated by :Lazy sync), package-lock.json~/.claude/settings.json (edited by Claude Code itself)~/.claude/skills/ (target for skill installation)lazyvim.json (updated by LazyVim framework)init.lua, config.fish, starship.toml~/.claude/rules/*.md{{ if eq .chezmoi.os "darwin" }}Place symlink_ entries at their natural target path. Source files live at repo root in .chezmoiignore.
# Directory structure
dot_config/nvim/
├── init.lua # copied normally
├── lua/plugins/... # copied normally
├── symlink_lazy-lock.json.tmpl # → source-managed lockfile
└── symlink_lazyvim.json.tmpl # → source-managed state file
nvim/ # repo root, in .chezmoiignore
├── lazy-lock.json # actual file (symlink target)
└── lazyvim.json # actual file (symlink target)
Each symlink_*.tmpl file contains a single line:
{{ .chezmoi.sourceDir }}/nvim/lazy-lock.json
The .chezmoiignore prevents chezmoi from also deploying nvim/ as ~/nvim/:
nvim/
This approach keeps the bulk of the config in normal chezmoi workflow while only the specific externally-modified files get symlink treatment. Attributes nest freely — symlink_ works inside dot_config/ or any other prefix directory.
Avoid symlinking a whole directory (e.g., ~/.config/nvim → source) just because one or two files in it are externally modified. This bypasses chezmoi's state management for the entire tree and prevents template processing on any file in that directory.
chezmoi's strength is declarative file management. Prefer static files over dynamic scripts, and copy over symlink.
Decision hierarchy:
dot_ prefix. Use .tmpl for OS/machine branching.symlink_ prefix inline.Scripts are a surface to minimize. Each script is an imperative action that can fail, has ordering concerns, and complicates debugging. If something can be a file, make it a file. Reserve run_once_ and run_onchange_ for truly imperative operations like brew bundle or chsh.
Plugin managers with file-based output (like Fisher for Fish shell) don't need install scripts in chezmoi. If the plugin manager just puts files into a tracked directory, track the output files directly and treat the plugin manager as a manual tool the user runs occasionally.
Templates use Go text/template with the expanded sprig library of functions.
Scripts in .chezmoiscripts/ run during apply. Format: run_[once_|onchange_][before_|after_]<order>-<name>.<ext>[.tmpl].
Hooks run before/after chezmoi commands (not during apply like scripts).
Pull from git repos/archives via .chezmoiexternal.yaml. Refresh with chezmoi apply -R.
chezmoi doctor # Check setup
chezmoi diff # Show pending changes
chezmoi cat ~/.bashrc # Show what would be written
chezmoi execute-template '{{ .chezmoi.os }}' # Test template
chezmoi state delete-bucket --bucket=scriptState # Reset run_once_ tracking
.chezmoi* files and directoriesGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub christianromney/claude-plugins --plugin chezmoi