2026-08-30 - How I Set Up My New MacBook

tl;dr: 1Password, then Homebrew, then SSH keys, then dotfiles. My dotfiles live in a private repo, and cloning it needs the SSH keys that the dotfiles were supposed to set up, so those four have to happen in that order. Everything after them is just install and sign in.


I set up a new MacBook this week and kept a checklist while I worked through it. Most of the list is dull: two dozen apps, a few toggles in System Settings. One line had a note I’d left myself in Vietnamese, phải chuẩn bị trước, vì không có cái này thì không down về được. That line was ssh config, and it turned out to be the only item that could actually hold me up.

The chicken-and-egg problem

My shell config, my aliases and my ~/.ssh/config (two GitHub identities plus GitLab) all live in one private dotfiles repo. Cloning that repo needs an SSH key GitHub already knows about, and the instructions for setting up the key are inside the repo. A brand-new Mac has nothing on it to break the loop with.

Two ways out:

  1. Prepare before wiping the old machine. Copy the SSH keys and ~/.ssh/config into 1Password while the old laptop still works. I moved the private keys through the vault rather than through chat or email.
  2. Generate fresh keys on the new machine and register them in the GitHub and GitLab web UIs. That works too, it’s just slower, and since I sign my commits it also means adding a second signing key to my allowed-signers list.

I did the first. The second is what I’d fall back on after forgetting, which is the more likely story.

The conditional includeIf setup I use to keep the two identities apart is in a separate note, How I Setup Multiple GitHub Accounts on My Laptop.

The order I used

  1. 1Password first. It holds the keys, the tokens and the passwords that the next twenty steps ask for. I signed in from Safari, before Chrome existed on the machine.
  2. Homebrew. It asks for the Xcode Command Line Tools and handles the rest. The only install that needs no credentials at all.
  3. SSH keys. Restore them from the vault, chmod 600 the private ones, drop in ~/.ssh/config, then check ssh -T git@github.com before trusting any of it.
  4. Dotfiles. Clone and link. zsh behaves like the old machine again: prompt, aliases, functions, PATH.
  5. Everything else, in whatever order. I installed the rest in the background while working.

Step 3 is the one I would have walked straight past without that note to myself.

The apps

My raw checklist was a flat list of names, which says nothing about what to install first. Grouped, the order mostly sorts itself out, because only the first group blocks anything.

Bootstrap

Nothing else works until these are in place.

  • 1Password: holds the keys, the tokens and the passwords the next twenty steps ask for. I sign in from Safari, before Chrome exists on the machine.
  • Homebrew: the only install that needs no credentials. It asks for the Xcode Command Line Tools and takes it from there.
  • SSH keys: restored from the vault, chmod 600 on the private ones, then verified with ssh -T git@github.com.
  • Ghostty: my terminal, and the first thing I want once brew is alive.
  • zsh: macOS already ships it. It only needs my config.
  • Dotfiles: one private repo with the shell config, the aliases and ~/.ssh/config. Everything above it exists to unblock this clone.

Dev toolchain

These go in right after the dotfiles land.

  • nvm: Node per project, because two of mine disagree about the version.
  • pnpm: my package manager everywhere.
  • Docker: for the services I don’t want installed natively.
  • VS Code: the main editor. Settings sync pulls the extensions back.
  • T3 Code: one GUI over several coding agents, worktrees included.
  • Claude Code: the terminal agent I use every day. It wants the dotfiles in place first.
  • Fork: reading history and staging hunks, the two things I don’t do from the CLI.

Desktop ergonomics

Small stuff, but I notice all of it within an hour.

  • Raycast: I use it instead of Spotlight, though the feature I really reinstall it for is clipboard history. I turn that on immediately, since it’s useless retroactively.
  • Rectangle: keyboard window snapping, halves and quarters.
  • Scroll Reverser: macOS gives me one scroll-direction toggle covering both trackpad and mouse. I want natural on the trackpad and inverted on an external mouse, and this is the only way I’ve found to get both.
  • Bluesnooze: turns Bluetooth off when the Mac sleeps and back on when it wakes, so a closed laptop stops stealing the headphones my phone is already playing to.
  • OhMyKey
  • Itsycal: a real calendar in the menu bar, which macOS still won’t show on click.

Accounts and work

Nothing to configure here, just sign-ins.

  • Chrome: the daily browser, once 1Password is there to fill it.
  • Slack: work.
  • Telegram: everything else.
  • Notion: notes and docs.
  • Figma: mostly for reading designs.

System Settings

Four changes I make in the first five minutes:

  • Keyboard → Text Input → Edit: turn off “Correct spelling automatically” and “Capitalize words automatically”. Autocorrect in a terminal or a code comment is a liability for me.
  • Keyboard: key repeat to fastest, delay until repeat to shortest. I navigate with held-down arrow keys constantly.
  • Displays: scaled to “More Space”. The default resolution wastes a third of a 14-inch screen.
  • Dock: auto-hide on, size down, and clear out the apps Apple pre-pinned that I’ll never open.

What I’d remember next time

The checklist looks like twenty-four items of roughly equal weight, and it isn’t. Twenty-three can happen in any order. One of them, the SSH key I need before I can download the config that explains how to make SSH keys, depends on my old machine still being alive.

So: copy the keys out before handing the old laptop back.