Personal dotfiles managed with chezmoi for cross-platform development environments.
- Cross-platform: Works on macOS (Intel/Apple Silicon), Arch Linux, and Debian
- Platform-aware templates: Darwin-only scripts and settings are excluded on Linux
- Machine-local identity data: Git identity and signing-key paths live in chezmoi data
- Portable shell startup: optional tools and Homebrew are discovered at runtime
- Modern shell setup: zsh with starship, atuin, and productivity tools
Install chezmoi:
# macOS
brew install chezmoi
# Linux
sh -c "$(curl -fsLS get.chezmoi.io)" -- -b $HOME/.local/bin# Initialize dotfiles (replace with your repo URL)
chezmoi init --apply https://github.com/yourusername/dotfiles.git
# Or for SSH
chezmoi init --apply git@github.com:yourusername/dotfiles.gitEdit ~/.config/chezmoi/chezmoi.toml to customize:
[data]
# Set these per machine; do not put an identity or key in the repository.
name = "Your Name"
email = "you@example.com"
context = "work" # or "personal"
# workstation enables 1Password-backed configuration; server does not.
profile = "workstation"
# Optional path used for GitHub SSH commit signing.
githubSigningKey = "~/.ssh/id_ed25519.pub"profile is a security boundary, not just a convenience setting:
- Use
profile = "workstation"only on a trusted, interactive Mac or Linux desktop. It enables 1Password-backed configuration and the local Kagi MCP wrapper. - Use
profile = "server"on EC2, VPS, CI, containers, and other remote hosts. This is the Linux default. It excludes 1Password configuration and Kagi, and does not requireopor a vault session. - macOS defaults to
workstation; set the profile explicitly on trusted Linux desktops.
For a trusted macOS workstation, install the 1Password CLI explicitly:
./bootstrap.sh --with-1passwordFor an EC2 or other remote host, use the regular bootstrap and set the profile before applying:
# ~/.config/chezmoi/chezmoi.toml
[data]
profile = "server"The managed SSH configuration sets ForwardAgent no, so a local 1Password SSH
agent is used to connect to a remote host but is never exposed on it. If a
server needs its own credentials, use a separate deploy key, cloud identity, or
a server-side secret manager—not your personal 1Password vault.
When adding a template that reads an op:// secret, guard it with the
workstation profile and exclude any generated secret-backed command on server
profiles.
- Shell:
.zshrcwith brew path detection - Git: Work/personal email templates
- SSH: Platform-aware keychain settings
- Terminal: starship, ghostty configurations
- Editor: Complete Neovim setup with plugins
- Tools: atuin (shell history), lazygit, gh (GitHub CLI)
- macOS: AeroSpace window manager and Homebrew bundle (Darwin-only)
- Arch Linux: native
pacmanpackage bootstrap; Homebrew is never installed - Debian: native
aptpackage bootstrap; Homebrew is never installed
Homebrew package lists are data-driven, following the same pattern as the example repository:
.chezmoidata/common.tomlcontains command-line tools shared with future platform installers..chezmoidata/darwin.tomlcontains macOS taps, formulae, casks, fonts, and App Store apps..chezmoidata/arch.tomlcontains Arch-specific pacman and optional AUR packages..chezmoidata/debian.tomlcontains Debian apt packages and packages that need an upstream source.private_dot_config/homebrew/Brewfile.tmplonly sorts, de-duplicates, and renders Homebrew data.
Edit the data files, then preview the generated bundle with:
chezmoi execute-template < ~/.local/share/chezmoi/private_dot_config/homebrew/Brewfile.tmpl# Check what would change
chezmoi status
# Apply changes
chezmoi apply
# Edit a config file
chezmoi edit ~/.zshrc
# Add new config file
chezmoi add ~/.config/newapp/config.yml# Pull latest changes
chezmoi update
# Or manually
cd ~/.local/share/chezmoi
git pull
chezmoi applySet the machine's Git identity by editing ~/.config/chezmoi/chezmoi.toml:
[data]
name = "Your Name"
email = "you@company.com"
context = "work"Then apply changes:
chezmoi applychezmoi add ~/.config/app/config.ymlchezmoi add --template ~/.config/macos-only-app/configThen edit the template to add conditionals:
{{- if eq .chezmoi.os "darwin" -}}
# macOS-specific config
{{- end -}}For configs with sensitive data, use 1Password integration:
chezmoi add --template ~/.config/app/config.ymlEdit the template:
api_key = "{{ onepassword "item-uuid" "api-key" }}"# Check template syntax
chezmoi execute-template < ~/.local/share/chezmoi/file.tmpl
# Debug template variables
chezmoi dataCheck that tools are installed and paths are correct:
# Verify brew prefix
echo $HOMEBREW_PREFIX
# Check tool locations
which starship atuin# Fix SSH permissions
chmod 600 ~/.ssh/config
chmod 700 ~/.ssh- Shell: zsh (default on macOS 10.15+)
- Package Manager: Homebrew (macOS/Linux)
- Git: For version control
- Neovim: Text editor
- 1Password CLI: Secret management
- Starship: Shell prompt
- Atuin: Shell history sync
- AeroSpace: macOS window manager
- Ghostty: Terminal emulator
#!/bin/bash
# Install common tools via Homebrew
# Core tools
brew install git neovim starship atuin
# Terminal tools
brew install bat lsd zoxide fzf direnv
# Development tools
brew install gh lazygit
# macOS-specific
if [[ "$(uname)" == "Darwin" ]]; then
brew install --cask aerospace ghostty
fi- Make changes to configs in
~/.local/share/chezmoi/ - Test with
chezmoi apply --dry-run - Commit and push changes
- Test on different platforms
Personal dotfiles - use at your own discretion.