Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

cade’s dotfiles

Personal dotfiles for macOS and Linux. One command bootstraps a complete dev environment — idempotent, no sudo on Linux, and (optionally) safe on shared NFS home directories across CPU architectures.

DF_NAME="Your Name" DF_EMAIL="you@example.com" \
  curl -fsSL https://raw.githubusercontent.com/cadebrown/dotfiles/main/bootstrap.sh | bash

DF_NAME / DF_EMAIL are needed when piping into bash (the pipe occupies stdin, so chezmoi can’t prompt); from a local clone, ~/dotfiles/bootstrap.sh prompts interactively. Re-run anytime to converge.

Pick your path:

GoalPage
Set up a brand-new machineBootstrap
Sync the latest changesDay-to-day workflow
Add or remove a toolPackage management
Understand PLAT isolationPLAT isolation
Set up API tokensAuth
Create a private extensionOverlays
Look up a DF_* flagEnv-var reference
Trace what bootstrap.sh actually doesBootstrap flow

What gets installed

Dotfiles and shell

chezmoi manages dotfiles as templates in home/ and applies them to ~/. Both zsh and bash get identical login profiles with PLAT detection, PATH setup, and tool activation.

  • zsh: oh-my-zsh with pure prompt, autosuggestions, fast-syntax-highlighting, completions, and lazy nvm loading (~140ms startup)
  • bash: minimal config with git branch prompt, shared aliases, zoxide, fzf completions
  • git: global config with name/email from chezmoi data, delta as pager
  • SSH: templated config from home/dot_ssh/config.tmpl

Packages

A single packages/Brewfile drives both platforms. On macOS, Homebrew installs native bottles plus casks (GUI apps). On Linux, Homebrew installs to a custom prefix ($_LOCAL_PLAT/brew/) with its own glibc — fully self-contained, no sudo.

if OS.mac? blocks in the Brewfile handle macOS-only casks and tools; Linux skips them silently.

Languages

LanguageToolInstall locationPackage list
Rustrustup + cargo-binstall$LOCAL_PLAT/rustup/, $LOCAL_PLAT/cargo/packages/cargo.txt
Node.jsnvm (lazy-loaded in zsh)$LOCAL_PLAT/nvm/packages/npm.txt
Pythonuv tool install (per CLI tool)$LOCAL_PLAT/uv/tools/, entrypoints in $LOCAL_PLAT/bin/packages/pip.txt

Rust tools install via cargo-binstall (downloads pre-built binaries from GitHub releases when available, falls back to source). Python CLI tools each get their own isolated venv via uv tool install — no monolithic user-level environment. On macOS, rustup comes from Homebrew (code-signed, required on Sequoia+ where the linker enforces provenance).

AI tools

  • Claude Code — native binary from Anthropic’s release bucket, plus plugins (packages/claude-plugins.txt) and MCP servers (packages/mcp-servers.txt)
  • Codex CLI — npm-installed binary (@openai/codex in npm.txt), with managed config + hooks under home/dot_codex/ and [mcp_servers.*] blocks generated from the shared packages/mcp-servers.txt
  • Cursor / VS Code — extension lists in packages/{cursor,vscode}-extensions.txt; Cursor settings symlinked from home/dot_cursor/

macOS-specific

  • System settings (install/macos-settings.sh) — Dock autohide, Finder extensions/path bar, fast key repeat, tap to click, PNG screenshots, Safari dev menu, iTerm2 prefs
  • Services (install/macos-services.sh) — Colima registered as a login service (rootless Docker without Docker Desktop)
  • Quick Actions (install/macos-quick-actions.sh) — Finder right-click “Open in Cursor” and friends

Auth (opt-in)

install/auth.sh is a guided service-registry helper that creates ~/.<service>.env files (chmod 600) for GitHub, Anthropic, OpenAI, Cloudflare, and HuggingFace — plus a separate gh auth login flow for the Claude GitHub MCP. Sourced automatically by all install scripts and login shells. Run during bootstrap with DF_DO_AUTH=1 or standalone anytime.

Home directories

install/dirs.sh creates ~/dev, ~/bones, and ~/misc (configurable via DF_DIRS). On systems with scratch space, these become symlinks directly under $SCRATCH/ for fast local storage. See Scratch space.


PLAT isolation (optional)

By default $LOCAL_PLAT = $HOME/.local and everything lives under a flat ~/.local/. PLAT isolation is opt-in — set DF_USE_PLAT=1 (or use_plat = true in chezmoi data) and $LOCAL_PLAT becomes ~/.local/$PLAT/. The point: on a shared NFS home, each machine installs into its own PLAT directory; one home directory, many machines, no conflicts. Single-machine users get the simpler flat layout without the per-PLAT directory tax.

DF_USE_PLAT=0  (default, flat)        DF_USE_PLAT=1  (NFS-shared homes)
─────────────────────────────         ───────────────────────────────────
~/.local/                             ~/.local/
├── bin/                              ├── plat_Darwin_arm64/
│   ├── chezmoi                       │   ├── bin/{chezmoi,uv,claude}
│   ├── uv                            │   ├── brew/        (Apple Silicon)
│   └── claude                        │   ├── cargo/bin/   (arm64 binaries)
├── brew/        (one prefix)         │   └── nvm/         (arm64 node)
├── cargo/bin/   (host arch)          ├── plat_Linux_x86-64-v3/
└── nvm/                              │   ├── brew/        (AVX2 glibc)
                                      │   └── ...
$_LOCAL_PLAT = ~/.local                └── plat_Linux_x86-64-v4/  (AVX-512)
                                          └── ...

                                      $_LOCAL_PLAT = ~/.local/$_PLAT
                                      (set per-shell from CPU detection)

Capability detection still runs in flat mode — .plat_env.sh tunes compiler flags (-march=x86-64-v3, RUSTFLAGS=-Ctarget-cpu=apple-m1, etc.) for the host CPU even when directory isolation is off. See PLAT isolation for the decision matrix.


macOS vs Linux

macOSLinux
PackagesHomebrew at /opt/homebrewHomebrew at ~/.local/$PLAT/brew/ (custom prefix, bundled glibc)
RustHomebrew rustup (code-signed for Sequoia)sh.rustup.rs
System settingsDock, Finder, keyboard, trackpad, Safari, iTerm2
ServicesColima (rootless Docker)
sudo requiredYes (Homebrew installer)No

Bootstrap modes

bootstrap.sh              # install (default) — full idempotent setup
bootstrap.sh update       # git pull + chezmoi apply + refresh tools
bootstrap.sh upgrade      # update + brew upgrade + cargo upgrade

Any step can be skipped with DF_DO_*=0 env vars. See Bootstrap for the full list.


Sections

Setup

PageWhat it covers
BootstrapSystem requirements, what gets installed, skip flags, modes
Managing dotfileschezmoi workflow, editing dotfiles, template variables, shared-home safety
Package managementAdding tools via cargo, npm, pip, or Homebrew
PLAT isolationWhen to use it, layouts compared, decommissioning
AuthService registry, env-file flow, gh-derive trick
Scratch spaceSymlink topology for NFS-quota relief
OverlaysPrivate extension repos (dotfiles-*/)

Usage

PageWhat it covers
Day-to-day workflowUpdating, adding packages, editing dotfiles
AeroSpace window managementTiling WM keymap (macOS)
Local AI codingOllama, mlx-lm, opencode, pi setup
TroubleshootingTools not found, PATH issues, build failures

Reference

PageWhat it covers
Env vars (DF_*)Complete table of every flag and behavior var
Bootstrap flowStep-by-step diagram of what bootstrap.sh does

Infrastructure

PageWhat it covers
Docs and hostingHow this site is built, deployed, and managed