Shell environment managed with a custom embedded Go tool.
I tried chezmoi and home-manager, but somehow these tools felt too complicated. This small Go application works fine for me.
| Tool | Purpose | Managed |
|---|---|---|
| Zsh | Shell | Config only |
| Antidote | Zsh plugin manager | Binary + Config |
| Starship | Prompt | Binary + Config |
| Atuin | Shell history | Binary + Config |
| direnv | Per-directory env vars | Binary + Config |
| mise | Installs and manages all the tools above | Binary |
| tmux | Terminal multiplexer | Binary + Config |
The base tools (Starship, Atuin, direnv, tmux) are declared in
templates/mise/dotfiles.toml. apply deploys that file to
~/.config/mise/conf.d/dotfiles.toml and then runs mise install, so mise itself decides what is
missing and installs it — the Go tool keeps no tool bookkeeping of its own.
To install extra / machine-specific tools, use mise directly:
mise use -g <tool>That writes ~/.config/mise/config.toml, a separate file dotfiles never touches — so your personal
tools and the managed base set never fight over the same file.
Antidote is not in the mise registry, so it is installed separately via git clone into
~/.antidote.
The templates are embedded into the Go binary using go:embed, so you can run the installer
directly from GitHub on any new machine.
You need Go and mise installed. (Zsh is expected to be installed via your system package manager.)
Create ~/.config/dotfiles/config.toml (TOML) from
config.example.toml:
name = "Your Name"
personal_email = "you@example.com"
[[orgs]]
url = "github.com/your-company"
email = "you@your-company.com"orgs generates a per-org ~/.gitconfig-org-<name> so repos under that org use the matching git
email.
Upgrading from the old YAML config? The config format is now TOML and there is no backwards compatibility. If a
~/.config/dotfiles/config.yamlis present, the tool prints a migration hint and refuses to run — convert it toconfig.toml(see above) and delete the old file. The oldmise_tools:key was removed; install extra tools withmise use -g <tool>instead.
To see what changes the tool would make to your machine without modifying anything (this also lists which mise tools are missing), run:
go run github.com/guettli/dotfiles@latest diffTo install the tools (via mise) and deploy your dotfiles:
go run github.com/guettli/dotfiles@latest applyTo overwrite local modifications, use the --force flag:
go run github.com/guettli/dotfiles@latest apply --forceOverwrite Protection: The tool maintains a hidden cache of what it previously installed. If you
have made un-tracked manual edits to a config file (e.g., you edited ~/.zshrc directly), the
apply command will abort and show you a diff, preventing accidental data loss. You can bypass
this with --force.
A common trigger is
~/.gitconfig: runninggh auth setup-gitappends a[credential "https://github.com"]helper block, which then diverges from the managed template and abortsapply. If you push over SSH you don't need that block — re-run with--forceto drop it; otherwise move the setting into a separate, unmanaged include soapplyleaves it alone.
If you want to edit the configurations:
- Clone the repository locally:
git clone git@github.com:guettli/dotfiles.git cd dotfiles - Modify the files inside the
templates/directory. - Test your changes locally before committing:
go run . diff go run . apply
- Commit and push. You can immediately run
go run github.com/guettli/dotfiles@latest applyon your other machines to sync.