Post-Mac-Setup: One Script to Bootstrap a New Mac
An idempotent Bash script that bootstraps a complete macOS development environment — Homebrew, CLI tools, GUI apps, Oh My Zsh, and shell config from a fresh install.
Every time I set up a new Mac — or nuke and reinstall — I go through the same tedious ritual: install Homebrew, then brew install fifty packages one by one, download apps, configure the shell, set defaults. It takes hours and I always forget something.
So I wrote a single Bash script that does everything. One command, one file, fully idempotent.
Post-Mac-SetupMITQuick Start
| chmod +x mac-setup.sh && ./mac-setup.sh |
Rerunning is safe — Homebrew skips already-installed packages, and shell configs are updated in-place using marker-based injection.
What It Installs
CLI Tools
The script installs everything I need for hardware design, software development, and general productivity:
| Category | Packages |
|---|---|
| Shells | bash, zsh |
| Version Control | git, git-lfs, gh |
| Languages | python@3, uv, node, pnpm, r, gcc, go, rustup |
| EDA / Hardware | icarus-verilog, yosys, verilator, verible, surfer, graphviz |
| File Navigation | eza, fd, fzf, zoxide, tree |
| File Inspection | bat, ripgrep, jq, coreutils |
| System Monitoring | htop, bottom, dust |
| Benchmarking | hyperfine, difftastic |
| Networking | wget, curl |
| Reference | tldr |
| Build Tools | cmake, llvm, pandoc |
| Homebrew TUI | bbrew |
GUI Apps
| Category | Apps |
|---|---|
| Editors & IDEs | VS Code, CotEditor |
| Git | GitHub Desktop |
| AI | Claude |
| Productivity | Microsoft Office, Setapp, Google Drive |
| LaTeX | MacTeX, Texifier |
| Research | Zotero, Inkscape |
| Terminal | iTerm2 |
| Networking | Tailscale, 1Password, 1Password CLI |
| Browser & Messaging | Ulaa, WhatsApp |
| Window Management | AltTab, Rectangle Pro |
| Menu Bar | Blip |
| Fonts | MesloLG Nerd Font, JetBrains Mono Nerd Font |
Shell Environment
The script sets up Oh My Zsh with Powerlevel10k and configures:
- Plugins: zsh-autosuggestions, zsh-syntax-highlighting, zsh-completions, fzf
- Aliases:
ezaasls,batascat,fdasfind,dustasdu,btmastop,difftasdiff, plus git shortcuts - Config files:
~/.zshrc,~/.zsh_paths,~/.zsh_aliases(cleanly separated)
Design Decisions
Why a Single File?
No framework, no dotfile manager, no symlinks. Just one Bash script you can curl and run. The tradeoff is less modularity — but for a personal setup script, simplicity wins.
Marker-Based Injection
This is the part I'm most proud of. Shell config blocks are wrapped in markers:
| ### BEGIN BLOCK-ID (managed by mac-setup.sh — do not edit) | |
| # ... managed content ... | |
| ### END BLOCK-ID |
Anything you add outside these markers is preserved across reruns. This means you can customize your .zshrc freely and still rerun the script without losing your changes. It's idempotent in the truest sense.
CLI Flags for Flexibility
| # See what would happen without making changes | |
| ./mac-setup.sh --dry-run | |
| # Install only CLI tools (no GUI apps) | |
| ./mac-setup.sh --skip-casks | |
| # Skip CLI tools, install only casks | |
| ./mac-setup.sh --skip-formulae | |
| # Minimal run — just packages, no shell or macOS config | |
| ./mac-setup.sh --skip-shell --skip-macos | |
| # Suppress log file output | |
| ./mac-setup.sh --no-log |
How It Works
- Preflight — verifies internet connectivity, installs Xcode Command Line Tools and Homebrew
- Install — taps third-party repos, installs formulae, casks, and npm globals
- Configure — sets up shells in
/etc/shells, configures Git, initializes Rust, fzf, and MacTeX - Shell Config — writes config files using marker-based block injection
- macOS Defaults — applies
.DS_Storeprevention on network and USB volumes - Cleanup — runs
brew cleanupand exports aBrewfilesnapshot
Post-Install
A few things still need manual steps after the script finishes:
- Restart your terminal (or
exec zsh) - Run
p10k configureto set up the Powerlevel10k prompt - Set iTerm2 font to MesloLGS Nerd Font (Preferences > Profiles > Text > Font)
- Verify Homebrew versions:
which git,which python3,which zsh - Sign in to apps: 1Password, Setapp, Tailscale, GitHub Desktop
Could these be automated too? Maybe. But they require GUI interaction or credentials, so I'm fine leaving them manual.
Try It
Clone it, swap in your own packages, and never manually set up a Mac again:
| git clone https://github.com/anirbanchakraborty-dev/Post-Mac-Setup.git | |
| cd Post-Mac-Setup | |
| ./mac-setup.sh --dry-run # preview first | |
| ./mac-setup.sh # full install |