Cross-platform dotfiles managed with chezmoi. Supports macOS (Homebrew), Arch Linux (pacman/yay), and Debian / Ubuntu (apt).
| Concern | Tool |
|---|---|
| Dotfile manager | chezmoi |
| Shell | Zsh (XDG-clean, no oh-my-zsh) |
| Prompt | Starship (Tokyo Night Night) |
| Terminal | Ghostty |
| Multiplexer | Zellij |
| Editor | Neovim (lazy.nvim, minimal) |
| AI coding agents | Claude Code + OpenCode + Codex + Antigravity CLI (configs tracked, CLIs self-installed) |
| Colour theme | Tokyo Night Night |
| Font | FiraCode Nerd Font Mono |
Replace your-github-user with the owner of your fork.
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install chezmoi
chezmoi init --apply your-github-user/dotfilessudo pacman -Syu --noconfirm git base-devel
# install yay (AUR helper)
git clone https://aur.archlinux.org/yay.git /tmp/yay && cd /tmp/yay && makepkg -si --noconfirm
# install chezmoi
yay -S --noconfirm chezmoi
chezmoi init --apply your-github-user/dotfilessudo apt-get update && sudo apt-get install -y curl git
# install chezmoi into ~/.local/bin
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b "$HOME/.local/bin"
export PATH="$HOME/.local/bin:$PATH"
chezmoi init --apply your-github-user/dotfilesOr, the all-in-one bootstrap (clones the repo, installs apt packages, starship, Nerd Fonts, and applies dotfiles):
git clone https://github.com/your-github-user/dotfiles "$HOME/.local/share/dotfiles"
bash "$HOME/.local/share/dotfiles/install.sh"For headless / SSH bootstrap (no tty), pre-seed the chezmoi data via env vars:
ssh host 'git clone https://github.com/your-github-user/dotfiles "$HOME/.local/share/dotfiles" && \
CHEZMOI_NAME="Your Name" \
CHEZMOI_EMAIL="you@example.com" \
CHEZMOI_GPG_KEY="" \
bash "$HOME/.local/share/dotfiles/install.sh"'(chsh still needs a password and is skipped in non-tty mode — run
sudo chsh -s "$(command -v zsh)" "$USER" afterwards.)
Ghostty and Zellij are not packaged for Debian — install them manually from ghostty.org and zellij.dev if you need them.
chezmoi init --apply your-github-user/dotfilesinstall.sh is non-destructive. Running it on a machine with an existing
~/.zshrc, ~/.zshenv, etc. will:
- back each one up to
<file>.pre-chezmoi.bakbefore chezmoi overwrites it - copy
~/.zsh_historyinto$XDG_STATE_HOME/zsh/history(the original is left in place — delete it whenever you're confident) - leave version managers (nvm, pyenv, jenv, rvm), oh-my-zsh, and any other unrelated tooling completely alone — clean those up yourself when ready
git clone https://github.com/your-github-user/dotfiles "$HOME/.local/share/dotfiles"
bash "$HOME/.local/share/dotfiles/install.sh"- A Nerd Font installed and selected in your terminal (FiraCode Nerd Font Mono recommended — installed by
install.shon every supported OS) - A GPG key if you want signed commits (optional; leave blank when prompted)
dotfiles/
├── Brewfile # macOS package manifest (brew bundle)
├── packages.arch.txt # Arch Linux package list (yay)
├── packages.debian.txt # Debian / Ubuntu package list (apt)
├── terminfo/ghostty.terminfo # xterm-ghostty terminfo source — compiled by install.sh
├── install.sh # one-command bootstrap (macOS / Arch / Debian)
├── home/ # maps to ~/ via chezmoi
│ ├── .chezmoi.toml.tmpl # chezmoi config — prompts for name/email/GPG key once
│ ├── dot_zshenv # sets ZDOTDIR, XDG vars
│ ├── dot_config/
│ │ ├── zsh/
│ │ │ ├── dot_zshenv # placeholder; zsh reads ~/.zshenv, not $ZDOTDIR/.zshenv
│ │ │ ├── dot_zshrc # thin bootstrap; sources conf.d/* + secrets.zsh + local.zsh
│ │ │ ├── secrets.zsh.example
│ │ │ ├── local.zsh.example
│ │ │ └── conf.d/ # modular config files sourced alphabetically
│ │ ├── starship.toml
│ │ ├── ghostty/
│ │ ├── zellij/
│ │ ├── nvim/
│ │ ├── git/
│ │ ├── opencode/ # OpenCode config (opencode.json, cli.json)
│ │ └── ccstatusline/ # Claude Code status-line config
│ ├── dot_claude/ # Claude Code base settings and keybindings
│ ├── dot_codex/ # Codex config + plan/review profiles → ~/.codex/
│ ├── dot_gemini/ # Antigravity CLI base settings → ~/.gemini/
│ └── dot_gnupg/
├── AGENTS.md # shared project instructions (Codex and Antigravity read directly)
├── CLAUDE.md # thin @AGENTS.md import for Claude Code
└── GEMINI.md # thin @AGENTS.md import for Antigravity CLI
All CLIs receive the same repo-root guidance: Codex and Antigravity CLI read
AGENTS.md, Claude Code reads the thin CLAUDE.md import, GEMINI.md provides
the equivalent thin import for Antigravity, and OpenCode declares AGENTS.md in
its instructions list.
| Tool | Source | Target |
|---|---|---|
| Claude Code | home/dot_claude/settings.json |
~/.claude/settings.json |
| Claude keybindings | home/dot_claude/keybindings.json |
~/.claude/keybindings.json |
| Claude statusline | home/dot_config/ccstatusline/settings.json |
~/.config/ccstatusline/settings.json |
| OpenCode (config) | home/dot_config/opencode/opencode.json |
~/.config/opencode/opencode.json |
| OpenCode (CLI) | home/dot_config/opencode/cli.json |
~/.config/opencode/cli.json |
| Codex | home/dot_codex/private_config.toml |
~/.codex/config.toml |
| Codex profiles | home/dot_codex/private_{plan,review}.config.toml |
~/.codex/{plan,review}.config.toml |
| Antigravity CLI | home/dot_gemini/antigravity-cli/settings.json |
~/.gemini/antigravity-cli/settings.json |
- The
claude,opencode,codex, andagybinaries themselves — all ship installers with built-in auto-update. PATH for Claude Code, OpenCode, and Antigravity CLI is set indot_zshenv/conf.d/exports.zsh. - Session state, credentials, plugin caches, history, and project/session data
under
~/.claude/,~/.codex/, and~/.gemini/antigravity-cli/— runtime data, never committed. - User- or service-specific Claude / Antigravity hooks, skills, plugins, and marketplaces.
- MCP server definitions for any agent. Configure integrations locally on each machine instead of committing endpoints or credentials.
- Per-project
CLAUDE.md/GEMINI.md/AGENTS.md— those live in each project repo.
To install the CLIs on a fresh machine:
# Claude Code (macOS / Linux)
curl -fsSL https://claude.ai/install.sh | bash
# OpenCode (macOS / Linux)
curl -fsSL https://opencode.ai/v2/install | bash
# Codex (macOS / Linux)
curl -fsSL https://chatgpt.com/codex/install.sh | sh
# Antigravity CLI (macOS / Linux)
curl -fsSL https://antigravity.google/install.sh | bash
# Status-line renderer (Claude Code & Antigravity CLI)
npm install -g ccstatuslineTwo files live at ~/.config/zsh/ for things that vary between machines.
Both are gitignored AND listed in home/.chezmoiignore, so chezmoi apply
will never overwrite them — edit them freely on each machine.
| File | For |
|---|---|
secrets.zsh |
Tokens, API keys, passwords (e.g. GITHUB_TOKEN, OPENAI_API_KEY) |
local.zsh |
Non-secret per-machine config (PATH additions, work-only aliases, env overrides) |
Both are sourced from dot_zshrc after conf.d/*, so anything you set wins
over the tracked defaults. Get started by copying the examples:
cp ~/.config/zsh/secrets.zsh.example ~/.config/zsh/secrets.zsh
cp ~/.config/zsh/local.zsh.example ~/.config/zsh/local.zsh
chmod 600 ~/.config/zsh/secrets.zsh
$EDITOR ~/.config/zsh/secrets.zsh ~/.config/zsh/local.zshSecrets are of two types. Put secrets that every shell needs as plain export
lines in secrets.zsh. Get all other secrets on demand from
Bitwarden Secrets Manager
with the bws CLI (install.sh installs it). Only BWS_ACCESS_TOKEN must be
in secrets.zsh; then use bws run -- <cmd> to give a command its secrets.
No secret is fetched at shell start. For day-to-day use, conf.d/bws.zsh has
pass-like helpers: bws-ls, bws-show KEY, bws-insert KEY and
bws-edit KEY. Set BWS_PROJECT_ID in local.zsh for bws-insert.
The example files are intentionally generic — there is no canonical list of expected variables. Add whatever your workflow needs.
# on source machine — edit files, then push
chezmoi cd
# make changes…
git add -A && git commit -m "feat: ..." && git push
# on any machine — pull and apply
chezmoi updateOr edit-in-place and let chezmoi sync back to the source:
chezmoi edit ~/.config/zsh/conf.d/aliases.zsh
chezmoi apply- Install the platform package manager — Homebrew (macOS),
git+yay(Arch), orapt(Debian / Ubuntu) — then run the quick-start commands above (orbash install.shfrom a clone). - Copy the per-machine override examples (
secrets.zsh.example→secrets.zsh,local.zsh.example→local.zsh) and fill in whatever you need. - Import your GPG key:
gpg --import private-key.asc
-
chezmoi diffis clean (no pending changes) - Ghostty opens, Zellij starts, Starship prompt renders
-
gpg --list-secret-keysshows your signing key -
git commitproduces a signed commit -
time zsh -i -c exit< 200 ms
chezmoi apply can set wrong permissions on ~/.gnupg/. Fix:
chmod 700 ~/.gnupg
find ~/.gnupg -type d -exec chmod 700 {} \;
find ~/.gnupg -type f -exec chmod 600 {} \;
gpgconf --kill allEnsure GPG_TTY=$(tty) is exported. It is set in conf.d/exports.zsh — open a fresh shell.
The data file is missing. Run:
mkdir -p ~/.config/chezmoi
cat > ~/.config/chezmoi/chezmoi.toml <<'EOF'
[data]
name = "Your Name"
email = "you@example.com"
gpgKey = "YOUR_KEY_ID"
EOF
chezmoi apply