Last active
March 7, 2026 21:04
-
-
Save jbnunn/035ed0f8e38c8ace26a249ad7a497cc4 to your computer and use it in GitHub Desktop.
Setup new Mac - The Basics (2026)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env bash | |
| # mac-setup.sh — Repeatable macOS bootstrap script | |
| # Usage: bash mac-setup.sh | |
| # Run this in a fresh terminal after a clean macOS install. | |
| set -e | |
| BREW="/opt/homebrew/bin/brew" # Apple Silicon path | |
| # ─── Helpers ────────────────────────────────────────────────────────────────── | |
| log() { echo ""; echo "==> $*"; } | |
| warn() { echo " [!] $*"; } | |
| # ─── 1. Homebrew ────────────────────────────────────────────────────────────── | |
| log "Installing Homebrew" | |
| if ! command -v brew &>/dev/null; then | |
| /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" | |
| # Add brew to PATH for the rest of this script | |
| eval "$($BREW shellenv)" | |
| else | |
| warn "Homebrew already installed, updating..." | |
| brew update | |
| fi | |
| # ─── 2. Shell integration ───────────────────────────────────────────────────── | |
| log "Adding Homebrew to shell profile" | |
| SHELL_PROFILE="$HOME/.zprofile" | |
| if ! grep -q "brew shellenv" "$SHELL_PROFILE" 2>/dev/null; then | |
| echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> "$SHELL_PROFILE" | |
| fi | |
| eval "$($BREW shellenv)" | |
| # ─── 3. CLI tools ───────────────────────────────────────────────────────────── | |
| log "Installing CLI tools via Homebrew" | |
| brew install uv node dockutil starship neovim stow | |
| # ─── 4. GUI apps (Casks) ────────────────────────────────────────────────────── | |
| log "Installing GUI apps via Homebrew Cask" | |
| brew install --cask \ | |
| google-chrome \ | |
| iterm2 \ | |
| ghostty \ | |
| orbstack | |
| # ─── 5. Dotfiles ────────────────────────────────────────────────────────────── | |
| log "Cloning and stowing dotfiles" | |
| if [ ! -d "$HOME/dotfiles" ]; then | |
| git clone https://github.com/jbnunn/dotfiles.git "$HOME/dotfiles" | |
| else | |
| warn "~/dotfiles already exists, skipping clone" | |
| fi | |
| # Ensure ~/.config is a real directory (not a symlink) | |
| if [ -L "$HOME/.config" ]; then | |
| unlink "$HOME/.config" | |
| fi | |
| mkdir -p "$HOME/.config" | |
| cd "$HOME/dotfiles" | |
| for pkg in bat btop eza ghostty ncspot neofetch nvim skhd starship tmux yazi; do | |
| stow --target="$HOME" "$pkg" && echo " stowed: $pkg" || warn "failed: $pkg" | |
| done | |
| cd "$HOME" | |
| # ─── 6. Shell config ────────────────────────────────────────────────────────── | |
| log "Configuring shell" | |
| if ! grep -q "starship init" "$HOME/.zshrc" 2>/dev/null; then | |
| echo 'eval "$(starship init zsh)"' >> "$HOME/.zshrc" | |
| fi | |
| if ! grep -q "case-insensitive" "$HOME/.zshrc" 2>/dev/null; then | |
| echo '' >> "$HOME/.zshrc" | |
| echo '# Case-insensitive tab completion' >> "$HOME/.zshrc" | |
| echo "zstyle ':completion:*' matcher-list 'm:{a-zA-Z}={A-Za-z}'" >> "$HOME/.zshrc" | |
| echo 'autoload -Uz compinit && compinit' >> "$HOME/.zshrc" | |
| fi | |
| # ─── 7. Keyboard settings ───────────────────────────────────────────────────── | |
| log "Configuring keyboard repeat rate" | |
| defaults write NSGlobalDomain KeyRepeat -int 2 | |
| defaults write NSGlobalDomain InitialKeyRepeat -int 15 | |
| defaults write NSGlobalDomain ApplePressAndHoldEnabled -bool false | |
| # ─── 8. Clean up Dock ───────────────────────────────────────────────────────── | |
| log "Clearing Dock (keeping only Finder)" | |
| # dockutil --remove all leaves Finder since it can't be removed from Dock | |
| dockutil --remove all --no-restart | |
| # Restart Dock to apply changes | |
| killall Dock | |
| # ─── 9. Done ────────────────────────────────────────────────────────────────── | |
| log "Done! A few things need manual attention:" | |
| echo "" | |
| echo " [ ] Log out and back in (or reboot) for all settings to take effect." | |
| echo "" | |
| echo " [ ] OrbStack launches like Docker — open it once to finish setup." | |
| echo "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment