chezmoi: Manage and Sync Dotfiles
chezmoi manages personal configuration for terminals, editors, and command-line tools, and brings the parts worth sharing to other machines. These files are often called dotfiles because many Unix configuration filenames begin with a dot, such as .bashrc and .gitconfig. The term also covers ordinary files inside .config.
Suppose two computers use the same terminal theme but different font sizes. Git can record the changes, but someone still has to decide where files belong, which values vary by machine, and whether application-written state should travel with them. chezmoi applies those decisions to local files; Git provides version history and transport between machines.
Source files and live files are different
In its default file mode, chezmoi does not symlink every configuration file back to the repository. It computes and writes destination files from its source state. The official quick start uses ~/.local/share/chezmoi as the default source directory; this location is configurable.
chezmoi edit edits the source, chezmoi diff compares the computed result with the destination, and chezmoi apply changes the destination. Editing a source file alone does not immediately change an application's configuration.
Install
Choose the appropriate method from the official installation page; these are alternatives, not a sequence:
Omarchy also provides its own package entry point: omarchy pkg add chezmoi. Run chezmoi --version afterward to confirm that the command is available. The local examples below were checked with chezmoi 2.72.1; package channels may provide different versions. Shell examples use a POSIX-style terminal on Linux, macOS, or WSL, not PowerShell syntax.
Try the workflow with one small file
This example assumes that chezmoi has not been configured yet and that the demo file does not exist. If you already use chezmoi, skip initialization and choose an unused demo path rather than overwriting an existing configuration.
chezmoi init
mkdir -p ~/.config/chezmoi-demo
printf 'theme = "dark"\n' > ~/.config/chezmoi-demo/settings.toml
chezmoi add ~/.config/chezmoi-demo/settings.toml
init creates a local source repository. add brings the selected file under management; it does not upload it. Open the source, change dark to light, save, and close the editor:
chezmoi edit ~/.config/chezmoi-demo/settings.toml
Preview the result, then apply it:
chezmoi diff ~/.config/chezmoi-demo/settings.toml
chezmoi apply --dry-run --verbose ~/.config/chezmoi-demo/settings.toml
chezmoi apply ~/.config/chezmoi-demo/settings.toml
The destination should now contain theme = "light". Running the same diff command again should show no changes. apply changes files; whether a running application picks them up immediately depends on its reload behavior. You may need to reload its configuration or restart it.
To locate the source directory or a particular source file, use:
chezmoi source-path
chezmoi source-path ~/.config/chezmoi-demo/settings.toml
chezmoi managed
When the application writes its own configuration
Some applications keep preferences such as a theme or default model in the same file as recent projects, window positions, or trust decisions. Sharing the entire file carries local state along with the settings. Symlinking it into Git also lets the application write directly into the repository.
chezmoi manages whole files by default. The next apply may overwrite application-made changes. Switching configuration managers does not automatically decide which fields belong on every machine.
When only a few settings should be shared, use a modify_ template. It receives the destination's current contents, changes selected fields, and produces the result.
Manage only the demo theme
Continue with the ordinary TOML file from the previous section. Rename its source file with a modify_ prefix. Querying the actual source path avoids guessing chezmoi's directory names:
source_file="$(chezmoi source-path ~/.config/chezmoi-demo/settings.toml)"
mv "$source_file" "$(dirname "$source_file")/modify_$(basename "$source_file")"
chezmoi edit ~/.config/chezmoi-demo/settings.toml
Replace the source in the editor with the following. This is a chezmoi template, not the TOML that the application will read:
{{/* chezmoi:modify-template */}}
{{- $config := .chezmoi.stdin | fromToml -}}
{{- $before := $config | toJson -}}
{{- $config = setValueAtPath "theme" "light" $config -}}
{{- if eq $before ($config | toJson) -}}
{{ .chezmoi.stdin }}
{{- else -}}
{{ $config | toToml }}
{{- end -}}
The marker on the first line enables modification-template behavior. Do not add a .tmpl suffix to this kind of file. .chezmoi.stdin contains the current destination, fromToml parses it, and setValueAtPath sets only theme. When that value already matches, the template returns the original text to avoid needless formatting changes.
Now simulate an application recording its most recent project:
printf '\nrecent_project = "/example/project"\n' >> ~/.config/chezmoi-demo/settings.toml
chezmoi diff ~/.config/chezmoi-demo/settings.toml
chezmoi apply ~/.config/chezmoi-demo/settings.toml
Because the theme is already light, diff should be empty and recent_project should remain in the live file. The source repository stores the theme rule, not the project entry. If the application changes the theme to dark, the next apply restores light while retaining the other field values.
This example serializes TOML again only when a managed field changes; at that point comments and formatting may be lost. For files whose comments must survive exactly, use a format-aware round-trip editing tool or the application's own include or local-override mechanism. If a real configuration is already symlink-managed, back it up and detach the old link before migrating, so two tools do not manage the same path.
Different values on different machines
For a configuration you maintain in full, without application write-back, use an ordinary template. Add a file for the first time with chezmoi add --template FILE, then edit it with chezmoi edit FILE.
Templates can read the operating system through .chezmoi.os or custom values under [data] in the machine-local ~/.config/chezmoi/chezmoi.toml. A fictional application's template might contain:
font_size = {{ if eq .chezmoi.os "darwin" }}14{{ else }}12{{ end }}
This selects 14 on macOS and 12 elsewhere. It is only an example of a condition: Windows and WSL may also use different configuration locations, and substituting a number does not make every application cross-platform.
An ordinary template generates the whole file; a modify_ template starts with the existing file. Choose the appropriate method for each destination. Do not re-add the previous section's modification template as an ordinary .tmpl file.
Bring the configuration to another machine with Git
Once the source repository contains only the non-sensitive configuration you intend to share, follow the official multi-machine workflow. Create an empty private dotfiles repository on your Git hosting service, then enter chezmoi's source directory:
chezmoi cd
This opens a subshell. Run the following there, replacing YOUR_USER with your own account. If a remote already exists, do not add origin again:
git status --short
git add .
git diff --cached
git commit -m "Manage example app settings"
git remote add origin git@github.com:YOUR_USER/dotfiles.git
git push -u origin HEAD
exit
A private repository is still not a place for passwords, cookies, private keys, or authentication files. Commit only the non-sensitive configuration you explicitly selected, rather than importing a whole home or application directory.
On another machine that has not yet been configured for chezmoi, install the tool and arrange repository access, then initialize and apply in separate steps:
chezmoi init git@github.com:YOUR_USER/dotfiles.git
chezmoi diff
chezmoi apply --dry-run --verbose
chezmoi apply
Use a source repository you control or have inspected; chezmoi repositories can also contain executable scripts. Reviewing the first diff, instead of immediately using init --apply, makes platform mismatches and existing configuration conflicts easier to spot.
For later updates, fetch the changes before deciding whether to apply them:
chezmoi git -- pull --ff-only
chezmoi diff
chezmoi apply
If Git reports divergence or conflicting local changes, resolve the differences rather than forcing an overwrite. The shortcut chezmoi update pulls and applies by default, and its default Git pull uses autostash and rebase. It is not a download-only command.
Which files should come first?
Start with one or two small files that contain no secrets and whose changes are easy to understand. Terminal themes and editor keybindings are useful first candidates for whole-file management. For files containing recent projects, trust decisions, or window state, choose the managed fields before writing a modification template. If an application already supports shared settings plus local overrides, prefer that existing arrangement.
You do not need to migrate every tool at once or write a general-purpose synchronization system. For each additional file, establish which values should be shared, which should remain local, and what the next apply will change.