This post is a living checklist for how I set up a new macOS machine for development. The source of truth is my dotfiles repo; this page is here to explain the flow and the “why”, not to become another set of instructions I forget to update.
- Dotfiles:
https://github.com/mehuaniket/dotfiles - Neovim config (vendored as a submodule inside dotfiles):
https://github.com/mehuaniket/kickstart.nvim
The setup philosophy (dotfiles-first)
I try to keep the setup reproducible and idempotent:
- Homebrew Bundle: for apps + CLI tools via a
Brewfile - GNU stow: for symlinking config into
$HOME(no copy/paste) - A single setup script: to glue everything together
If you only read one thing, read ~/.dotfiles/scripts/setup.sh. That’s what I actually run.
Before you start (5 minutes that saves hours)
- Install Xcode Command Line Tools (git/make/etc.):
xcode-select --install
- Decide if you want “dotfiles to win”:
- If you already have
~/.zshrc,~/.config/nvim, or~/.config/tmux, stow may conflict (and the script will warn). - I usually back up old configs first (rename the old directories/files), then run the script.
- If you already have
Safety note (about running remote scripts)
The one-liner uses curl to download and run a script. I do it for convenience on new machines, but:
- Inspect it first:
~/.dotfiles/scripts/setup.sh(or the same file in the GitHub repo) - Prefer the local clone approach if you want maximum transparency
Quick start (recommended)
Clone dotfiles and run the setup script
This is the “use my dotfiles” path (local, explicit, easy to inspect):
git clone --recurse-submodules https://github.com/mehuaniket/dotfiles ~/.dotfiles
bash ~/.dotfiles/scripts/setup.sh --brew
If Homebrew packages are already installed, you can omit --brew:
bash ~/.dotfiles/scripts/setup.sh
One-liner variant (same script, remote)
If you’re on a fresh machine and want to run the same setup script directly:
zsh -c "$(curl -fsSL https://raw.githubusercontent.com/mehuaniket/dotfiles/main/scripts/setup.sh)" -- --brew
Note the -- --brew: the first -- separates zsh -c args from the script args.
What the setup script does
The script (~/.dotfiles/scripts/setup.sh) is opinionated, but it’s pretty straightforward:
- Homebrew (optional):
- Installs Homebrew if missing
- Runs
brew bundle --file="$HOME/.dotfiles/homebrew/Brewfile"(reproducible installs) - Ensures a few key formulas/casks exist (things like
fzf,fd,ripgrep,tmux,neovim,kubectl,terraform,gh, nerd fonts,stow, etc.)
- Zsh:
- Installs Oh My Zsh (if missing)
- Installs plugins:
zsh-autosuggestionszsh-syntax-highlighting
- Installs Powerlevel10k
- Tries to set your login shell to Zsh (
chsh) if needed
- tmux:
- Installs TPM (tmux plugin manager) into
~/.config/tmux/plugins/tpm - Sources tmux config and installs plugins
- Installs TPM (tmux plugin manager) into
- Dotfiles linking (stow):
- Runs
stowfor a default set of modules:zsh,tmux,fzf,nvim - Uses
.stowrc(target is~/and ignores things likescripts/,homebrew/,misc/, etc.)
- Runs
Where the configs land (what gets symlinked)
These are the important “resulting paths” after stow runs:
- Zsh:
~/.zshrc,~/.p10k.zsh - tmux:
~/.config/tmux/tmux.conf - fzf/fd:
~/.fdignore - Neovim:
~/.config/nvim/
Manual steps (still required)
There are a few things I keep manual because they’re UI-driven:
- iTerm profile: import
~/.dotfiles/misc/iterm_default_profile.json- iTerm2 → Settings → Profiles → Other Actions → Import JSON Profiles
- (Optional) iTerm colors: import
~/.dotfiles/misc/catppuccin_mocha.itermcolors - Restart your terminal
- Open Neovim once so plugins can install/sync:
nvim
If you want to be explicit inside Neovim: run :Lazy and then :Lazy sync.
Optional dotfiles modules (things you may also want)
The setup script stows zsh, tmux, fzf, nvim. I also keep other modules in the repo that you can opt into:
cd ~/.dotfiles
stow git k9s hammerspoon delta
git/: git config + commit message templatek9s/: myk9sconfig + skinshammerspoon/: window management / hotkeys via Hammerspoondelta/: terminal theming bits (e.g.batthemes)
Day-2 operations (upgrades / reruns)
Updating the repo:
cd ~/.dotfiles
git pull --recurse-submodules
Re-running the setup (safe to re-run):
bash ~/.dotfiles/scripts/setup.sh
If you want to re-apply Homebrew bundle too:
bash ~/.dotfiles/scripts/setup.sh --brew
Or run brew bundle directly:
brew bundle --file=~/.dotfiles/homebrew/Brewfile && brew cleanup
Cheatsheet (the stuff I actually use daily)
tmux
- Prefix: Ctrl + Space
- New window: Prefix +
c - Split:
- Prefix +
"(horizontal) - Prefix +
%(vertical)
- Prefix +
- Move between panes (vim-style): Prefix +
h/j/k/l - Move between panes (no prefix): Alt + Arrow keys
- Switch windows (no prefix): Shift + Left/Right
If you ever get lost, re-source the config:
tmux source-file ~/.config/tmux/tmux.conf
Neovim
- Leader key: Space
- Move between splits: Ctrl +
h/j/k/l - Search files:
<leader>sf - Search keymaps:
<leader>sk - Search in current buffer:
<leader>/ - Search Neovim config:
<leader>sn
Debugger (DAP):
- Start/Continue: F5
- Step into/over/out: F1 / F2 / F3
- Toggle breakpoint:
<leader>b - Toggle DAP UI: F7
Troubleshooting (common gotchas)
stow conflicts
If the script says stow failed for a target (like zsh or nvim), you probably already have files at the destination path.
- For example,
zshwants to manage~/.zshrc nvimwants to manage~/.config/nvim/
Fix: move the old file/dir out of the way and re-run the script.
Homebrew shellenv not applied
If brew installs but your shell can’t find it, restart the terminal once, or run:
eval "$(/opt/homebrew/bin/brew shellenv)"
tmux plugins didn’t install
Inside tmux, try re-sourcing the config:
tmux source-file ~/.config/tmux/tmux.conf