A clean machine
Two years after a colleague's dotfiles scrolled past in my GitHub feed, a new laptop finally forced the issue. How I rebuilt my Mac as a repo with chezmoi, ran my once-a-year tool review as a conversation with Claude, and automated the parts I used to click through.
In the last post I set myself a goal for the first ninety days: a five-minute cold start. Fresh laptop to running code in under five minutes — clone the project, run it locally, hit a live endpoint, pass the tests, all before your coffee goes cold. The shortest honest path from a new hire’s first morning to their first real contribution. That’s the on-ramp I want to build for the team at GolfNext, the Danish golf-tech company I’m about to join.
Before I can hand that to anyone else, I owe it to my own machine. A new job means a new MacBook is on the way, so I pointed the same goal at myself first.
The two-year-old bookmark
About two years ago, a dotfiles repo rolled past in my GitHub timeline — the feed of what the people you follow are working on. It belonged to Manuel Brandstetter, a former colleague and one of the best engineers I’ve worked alongside. He took over as lead of scrumlr.io, the open-source retrospective tool I helped build, after I left inovex, the German consultancy where we’d worked together. So when his setup scrolled by, I stopped to look. No grand pitch, just there in passing: everything that makes a laptop his laptop, version-controlled in one place. I remember thinking, clearly and out loud, “I should do that.” Then I didn’t. For two years.
If you’ve never kept dotfiles: they’re the small config files that quietly shape your machine. Your shell setup, your editor settings, your git config — the dozens of little preferences you’d otherwise rebuild by hand, from memory, every time you get a new computer. A dotfiles repo puts them under version control so the machine becomes reproducible instead of hand-crafted and forgotten.
The reason I never got around to it is the boring one: it always felt like an afternoon I could spend on something more urgent. The thing about a brand-new laptop, though, is that it removes the excuse. You’re going to set the machine up anyway. You may as well set it up once, properly, in a way you never have to repeat.
The audit I run every December
There’s a habit I’ve kept for years. Somewhere in the quiet week around Christmas, I sit down and audit my tools. Am I still using the best thing for each job, or just the thing I happened to pick three years ago and never questioned? It’s usually a solo afternoon — reading changelogs, half-remembered Hacker News threads, a bit of “what’s everyone else using now.”
This year had a running start. A few weeks earlier I’d gone looking for something like nvm, but for every runtime, not just Node: Python, Go, Java, the lot. I found mise, which does exactly that, and swapping a drawer full of per-language version managers for a single one was the most satisfying thing I’d done to my setup in months. That small win, I suspect, is what quietly tipped a two-year-old “I should do that” into “do it now.”
So this year I ran the audit as a conversation instead. I pointed Claude — Anthropic’s AI assistant, the same one I’ll be building with at work — at my current setup and asked the blunt version of the question: what here is dated, what’s missing, what would you change, and why. Then I let it research and argue its case.
I kept the result honest by making it a diff. The old setup stayed on my main branch; the reviewed one went on a branch I called cleanup. So every recommendation was a line I could read, accept, or reject, not a black box rewriting my machine while I wasn’t looking. That framing mattered more than I expected. A review you can read line by line is a review you actually trust.
Two things came out of it: a way to treat the whole machine as one repo, and a short list of tools I’d been silly to skip.
chezmoi: the machine as a repo
The manager is chezmoi. It tracks your dotfiles in a git repo and renders them onto any machine you own — chez moi, fittingly, French for “at my place.”
What sold me over a plain folder of symlinks is the model. The files in the repo are the source of truth; you apply them to write the real files into your home directory. Edit, preview the diff, apply, commit. It templates (one file can adapt to a work machine versus a personal one), and it keeps secrets out of the repo entirely — my SSH keys stay inside 1Password, handed to git on demand, never written to a file chezmoi could accidentally commit.
The part that finally delivered on the two-year promise is the bootstrap. On a clean Mac, the whole machine comes back from three commands:
brew install gh chezmoi
gh auth login # sign in to GitHub in the browser
chezmoi init --apply bitionaire/dotfiles # clone + render everything into place
That last line clones the repo, installs my shell framework, lays down every config file, and runs a set of first-time setup scripts. One naming convention does most of the magic: a file called dot_zshrc in the repo becomes ~/.zshrc on the machine. dot_config/ghostty/config becomes ~/.config/ghostty/config. The dot_ prefix is just chezmoi’s way of writing a leading dot without confusing your file browser. Once that clicks, the repo reads like a mirror of your home directory.
The tools the review actually changed
I already ran oh-my-zsh with the powerlevel10k prompt. The review pushed three additions hard, and was right about all three:
- Ghostty — a fast, modern terminal. I’d been on the macOS default for years out of pure inertia. Ghostty is quicker, themeable in a plain text file (which means chezmoi can track it), and renders the powerline glyphs my prompt uses without a separate Nerd Font install.
- fzf — a fuzzy finder, and the one that changed my day-to-day most.
Ctrl-Rturns shell history from a blind up-arrow hunt into a live fuzzy search.Ctrl-Tdrops a file path into whatever you’re typing. Pipe anything into it —git branch | fzf— and you get an interactive picker for free. - zoxide — a smarter
cd. It learns the directories you actually use and lets you jump by a fragment of the name.z dotlands me in my dotfiles repo from anywhere on the machine, no matter how deep it’s buried.
None of these are exotic — they’re tools a lot of terminal-heavy people already swear by, and I’d simply never sat down to add them. Wiring them in is a few lines of shell config:
# fzf — fuzzy finder (Ctrl-R history search, Ctrl-T file picker)
command -v fzf >/dev/null 2>&1 && eval "$(fzf --zsh)"
# zoxide — smarter cd (`z <dir>` jumps by frequency + recency)
command -v zoxide >/dev/null 2>&1 && eval "$(zoxide init zsh)"
Automating the parts I used to click through
A fresh Mac isn’t just dotfiles. It’s an afternoon of downloading apps, dragging them to Applications, and clicking through the same System Settings toggles you’ve set on every Mac you’ve ever owned. That’s the part the review automated, and it’s the part I’m proudest of.
Apps come from a single Brewfile — a manifest Homebrew reads to install everything in one shot:
brew bundle --file=Brewfile # installs every CLI tool, app, and App Store entry
One file lists the command-line tools, the desktop apps (1Password, Firefox, Ghostty, Docker, the editor), and even Mac App Store purchases. New machine, one command, twenty-odd apps install themselves.
Then there are the macOS settings. chezmoi runs setup scripts on first apply, and one of them is just a list of defaults write commands — the scriptable side of System Settings. A taste:
defaults write -g KeyRepeat -int 2 # fast key repeat
defaults write -g ApplePressAndHoldEnabled -bool false # hold a key to repeat it
defaults write com.apple.finder AppleShowAllFiles -bool true # show hidden files
defaults write com.apple.finder _FXSortFoldersFirst -bool true # folders on top
I’d set every one of these by hand on every Mac for a decade and never thought to write them down — now they’re a file. It isn’t total. Apple deliberately blocks scripting the security-sensitive bits, so granting accessibility permissions and signing into iCloud stays manual. But the dozens of little toggles that used to eat an afternoon now take seconds, and I’ll never have to remember them again.
A good review cuts as much as it adds
The surprise was how much the conversation talked me out of. A tool audit isn’t only about new toys; it’s about noticing the cruft you’ve been carrying.
So the cleanup branch deleted things. The handful of older version managers I’d accumulated, plus a hand-installed Python, all folded into the one mise I’d adopted a few weeks before. A shortcut I’d wired up to work around an old Docker quirk that’s since been fixed — gone. A tangle of work-versus-personal git config I’d accreted across jobs, flattened back to a single identity. Each of those was a small decision I’d made years ago for a good reason, then never revisited once the reason expired.
That’s the real value of doing this with a sparring partner. Left alone, I tend to add. Asked to justify each piece out loud, I finally removed.
What I’m taking from it
The impressive part wasn’t that an AI can write a config file — everyone knows it can now. It was the review. It didn’t hand me a generic “best setup”; it looked at mine, asked what I actually do all day, and argued for changes that fit, with the reasoning attached so I could push back where it was wrong. Less a tool than the December audit I already run, with someone knowledgeable sitting across the table.
And it closed a loop. The five-minute cold start I want to give the GolfNext team is this same thing, scaled up: a new person, a new laptop, and a short path to real work without a week of setup tax. I built the personal version first.
So if you’ve got your own “I should do that” bookmark gathering dust — a repo that once scrolled past in your timeline, maybe — this is your sign. Wait for the next clean machine. Then set it up once. Two years late still beats never.
References
The tools and docs worth bookmarking, roughly in the order they show up above:
- chezmoi — dotfiles manager. Start with the quick start and the user guide.
- Homebrew and the Brewfile /
brew bundle— install apps and CLI tools from one manifest. - oh-my-zsh — Z shell framework, with the powerlevel10k prompt theme.
- Ghostty — fast, config-as-text terminal.
- fzf — command-line fuzzy finder.
- zoxide — a smarter
cdthat learns your habits. - mise — one version manager for node, python, go, and the rest.
- 1Password SSH agent — keep private keys out of the repo and off disk.
- The repo that started it: Manuel Brandstetter’s dotfiles.
P.S. — a Dock trick that has nothing to do with dotfiles
One freebie for the Mac users who made it this far. It has nothing to do with any of the above, but it’s the kind of small thing that’s quietly pleased me for years: you can drop blank spacers into the Dock to break your apps into clusters. Same defaults write trick as the rest of the post. Run it once per spacer you want:
# full-height spacer (run again for each extra one)
defaults write com.apple.dock persistent-apps -array-add '{tile-data={}; tile-type="spacer-tile";}' && killall Dock
# half-height spacer (run again for each extra one)
defaults write com.apple.dock persistent-apps -array-add '{"tile-type"="small-spacer-tile";}' && killall Dock
Drag the spacers around like any other Dock icon, or drag one off the Dock to remove it. Tiny thing. Makes a crowded Dock feel organized.
