The same checklist, every time a Mac gets set up (or reset) for development work — worth having written down instead of relying on memory.
Xcode Command Line Tools first
Most development tooling on macOS depends on these being installed — Git, compilers, and headers used by many package managers.
xcode-select --installHomebrew — the package manager
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"Once installed, everything else becomes a one-liner:
brew install git node python go
brew install --cask visual-studio-code docker iterm2brew install is for command-line tools and libraries; brew install --cask is for GUI applications — a distinction worth knowing since mixing them up is a common early confusion.
Shell setup
macOS defaults to zsh. A few worthwhile additions:
brew install starship # fast, customizable prompt
brew install fzf # fuzzy finder for files, command history, etc.
brew install eza # a modern replacement for ls with better defaultsAdd to ~/.zshrc:
eval "$(starship init zsh)"
alias ls="eza"Git configuration
git config --global user.name "Your Name"
git config --global user.email "you@example.com"
git config --global init.defaultBranch main
git config --global pull.rebase trueSSH keys for GitHub/GitLab
ssh-keygen -t ed25519 -C "you@example.com"
eval "$(ssh-agent -s)"
ssh-add --apple-use-keychain ~/.ssh/id_ed25519The --apple-use-keychain flag stores the passphrase in macOS Keychain so you're not re-entering it every session.
Node version management
Install Node via a version manager, not directly via Homebrew — you'll almost certainly need different Node versions across projects:
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
nvm install --ltsSystem settings worth changing
- System Settings → Keyboard → Key Repeat: set to fastest, and Delay Until Repeat to shortest — the defaults are noticeably sluggish for anyone typing all day.
- System Settings → Trackpad → Tap to Click: enable it — clicking by pressing down is slower than a light tap.
defaults write com.apple.dock autohide-delay -float 0— removes the Dock's auto-hide delay, from Terminal, if you keep the Dock hidden.
1
Xcode Command Line Tools
2
Homebrew
3
Shell + Git + SSH
4
Version-managed runtimes
A minimal but complete toolkit
By the end of this checklist: Homebrew for packages, a version-managed Node/Python setup, a configured shell with a fast prompt and fuzzy search, working Git and SSH auth, and a couple of system settings that remove daily friction. That's enough to be productive — everything else (specific editors, specific languages) layers on top of this base the same way regardless of project.
Homebrew itself (installed in the step above) has more to it than the one-liner install command — see Homebrew explained for the formulae-vs-casks distinction and the day-to-day commands worth knowing beyond install.
Terminal and dotfiles
Terminal.app works, but iTerm2 (installed above via --cask) is worth the switch for split panes, better search, and profile-based color schemes. Either way, the setup that actually saves time long-term is keeping your shell config in a dotfiles repo instead of only on the machine itself:
mkdir ~/dotfiles && cd ~/dotfiles
git init
cp ~/.zshrc ~/.gitconfig .
git add . && git commit -m "Initial dotfiles"Symlinking from the repo into your home directory (rather than copying) means edits to ~/.zshrc are automatically tracked:
ln -sf ~/dotfiles/.zshrc ~/.zshrc
ln -sf ~/dotfiles/.gitconfig ~/.gitconfigThe payoff shows up the next time this checklist needs running — git clone the dotfiles repo, re-run the symlink step, and most of the shell configuration from this guide is back instantly, instead of retyped from memory.
Editor setup: a minimal but complete VS Code config
Beyond installing the editor itself, a few settings changes remove friction most default installs leave in place:
// settings.json
{
"editor.formatOnSave": true,
"files.trimTrailingWhitespace": true,
"editor.rulers": [100],
"terminal.integrated.fontFamily": "CascadiaCode Nerd Font"
}editor.formatOnSave paired with a project's own Prettier/ESLint config means formatting is never a manual step or a PR review comment — it happens automatically on every save, consistent with whatever the project's own tooling already enforces.
Keeping Homebrew itself healthy
Homebrew accumulates cruft over time — old formula versions, downloaded cache files that never got cleaned up. A quick periodic maintenance pass keeps it from silently consuming disk space:
brew update && brew upgrade
brew cleanup
brew doctorbrew doctor specifically flags common misconfigurations (a stray Python install shadowing Homebrew's, permission issues in /usr/local or /opt/homebrew) before they cause a confusing failure in the middle of installing something unrelated.
Docker on macOS: a quick note on performance
Docker Desktop is the default choice, but its default file-sharing implementation can make bind-mounted volumes (a local project directory mounted into a container) noticeably slower than on native Linux — worth knowing before assuming a slow npm run dev inside a container is an application problem. Enabling VirtioFS (Docker Desktop's newer, faster file-sharing backend, on by default in current versions) or switching to Colima as a lighter-weight alternative daemon are both worth trying if container-based development feels sluggish specifically around file I/O rather than CPU-bound work.
Common mistakes
- Skipping
xcode-select --installand running straight intobrew install— many formulae depend on the Command Line Tools to build, and the resulting error message doesn't always make that dependency obvious. - Installing Node or Python directly via Homebrew, then hitting a project that needs a different version months later with no clean way to switch — install version managers (nvm, pyenv) from day one instead of retrofitting them.
- Generating a new SSH key without checking whether one already exists (
ls ~/.ssh) — overwriting an existing key you forgot about breaks auth on every service that already trusted the old one. - Never adding the new SSH public key to GitHub/GitLab after generating it — the key exists locally but git operations over SSH still fail with a permission error until the public half is actually added to your account.
Related reading
- Homebrew Explained: The macOS Package Manager for Developers — shares tags: macos, productivity (same category).
- Big O Notation Without the Math Panic — shares tags: productivity.
- Clean Code Principles That Actually Hold Up in Practice — shares tags: productivity.
- Understanding Cloud Cost Optimization Basics — shares tags: productivity.
- Git Hooks Explained: Automate Your Workflow — shares tags: productivity.