Using Homebrew Brewfile for Reproducible macOS Setups
Learn how to use Homebrew's Brewfile to declare and enforce your macOS development environment, with a worked example and notes on cleanup risks.
29 Aug 2026, 09:05 UTC

Problem: drifting development environments
When you set up a new Mac or reinstall macOS, it’s easy to forget which Homebrew packages, casks, or Mac App Store apps you actually need. Manually re‑installing each tool leads to inconsistent setups across teammates and makes onboarding slower.
Thesis: a Brewfile lets you declare the exact software you want and let Homebrew enforce it
By committing a simple Brewfile to your dotfiles repository, you can run brew bundle to install missing items, upgrade outdated ones, and optionally clean up anything that isn’t listed. This turns your workstation configuration into version‑controlled infrastructure.
How Brewfile works
A Brewfile uses Ruby‑like syntax. Each line can declare a formula, a cask, a tap, or a Mac App Store (mas) entry. Example:
# Tap additional repositories
tap 'homebrew/cask'
tap 'homebrew/cask-versions'
# Core utilities
brew 'git'
brew 'node@18', link: true
# GUI applications
cask 'visual-studio-code'
cask 'docker'
# Mac App Store apps (requires mas-cli)
mas 'Slack', id: 803453959
Running brew bundle in the directory containing this file will:
- Install any formula, cask, or mas app that is missing.
- Upgrade those that are outdated but still satisfy the version constraints.
- Leave untouched items that are already at the desired version.
Worked example: verifying a minimal setup
- Open a terminal (no special permissions needed; Homebrew runs as your user).
- Create a temporary directory and a minimal Brewfile:
mkdir -p /tmp/brew-demo && cd /tmp/brew-demo
cat > Brewfile <<'EOF'
brew 'git'
EOF
- Run the bundle command:
brew bundle
Homebrew will output something like:
==> Brewing git
==> Pouring git--2.45.0.arm64_ventura.bottle.tar.gz
🍺 /opt/homebrew/Cellar/git/2.45.0: 1,763 files, 38.2MB
To confirm the installation, run:
brew list git # should show git
git --version # prints the version
If you later decide you no longer want git managed by the Brewfile, simply remove the line and run brew bundle --cleanup. Homebrew will then uninstall git because it is no longer listed. Risk: the --cleanup flag removes any formula not present in the Brewfile, including dependencies you may have installed manually elsewhere. Always review the list of items that will be removed before proceeding.
Trade‑offs and limitations
- Version pinning: You can specify
brew 'foo', '1.2.3'but if a formula’s dependencies change, the pinned version may become incompatible, requiring manual review. - No custom build options: Brewfile cannot pass
--with‑xyzflags; you need a separate formula or manual install for such tweaks. - Cleanup danger: As noted,
--cleanupwill purge everything not declared, which can break tools you installed outside the Brewfile.
Practical check: after running brew bundle, execute brew bundle --check. It returns exit code 0 if the installed set matches the Brewfile; a non‑zero code indicates drift, which you can inspect with brew bundle --list to see what is missing or extra.
Actionable closing
Add a Brewfile to your dotfiles repository, commit it, and make brew bundle part of your onboarding script or CI pipeline. Periodically run brew bundle dump to update the file with any new tools you’ve adopted, and review the diff before committing. This gives you a reproducible, version‑controlled macOS workstation with minimal manual effort.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.