The problem with "set up your machine" docs
Most teams have a setup wiki page. It is almost always out of date. Someone installs a new tool, the page does not get updated, and three months later a new hire spends an afternoon discovering that a build silently fails because they are missing a dependency nobody remembered to write down. The root issue is that prose instructions and the actual state of machines drift apart the moment they are written.
A Brewfile fixes this by making the setup executable. Instead of a list of steps a human follows imperfectly, you have a file a machine runs identically every time. The documentation and the action become the same artifact.
One file, one command, every machine
The core pattern is simple. The team keeps a Brewfile in a repository, and onboarding becomes two commands after installing Homebrew:
git clone https://github.com/your-org/dev-setup.git
cd dev-setup && brew bundle install
Every engineer ends up with the same compilers, databases, CLIs, and apps. When someone adds a tool, they add a line, open a pull request, and the change is reviewed like any other code. The next person to run brew bundle install picks it up automatically.
Bundle it with dotfiles
Most teams that do this well pair the Brewfile with a dotfiles repository — shell config, editor settings, Git aliases — so a fresh machine gets not just the tools but the configuration to use them. A small bootstrap script ties it together:
#!/usr/bin/env bash
set -euo pipefail
# 1. Install Homebrew if missing
which brew >/dev/null || /bin/bash -c \
"$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# 2. Install every tool the team relies on
brew bundle install --file=./Brewfile
# 3. Link shared dotfiles into place
./link-dotfiles.sh
The result is a single script that takes a blank laptop to a fully working environment with no manual decisions in between.
Keep environments from drifting
Consistency is not a one-time event; machines drift as people experiment. Two habits keep a team aligned:
- Treat the Brewfile as the source of truth. Periodically run
brew bundle checkto confirm a machine matches the file, andbrew bundle cleanupto surface tools that were installed outside it. - Re-dump deliberately, not automatically. When the team agrees to adopt a tool, add it explicitly rather than dumping one person's entire machine — that keeps the shared file free of personal preferences.
Use it beyond laptops
Because a Brewfile is just a declarative list, the same file can provision more than developer machines. Homebrew runs on Linux too, so a Brewfile can install the same toolchain inside a CI runner, ensuring the environment that builds and tests your code matches the one developers use locally. The closer those two environments are, the fewer "works on my machine" bugs survive to production.
Separate the shared from the personal
A practical refinement is to split the file. Keep a team Brewfile with the tools everyone genuinely needs, and let individuals layer a personal Brewfile on top for their own preferences. Running both is trivial:
brew bundle install --file=./Brewfile # shared, reviewed
brew bundle install --file=~/Brewfile.personal # your own extras
This keeps the shared file small and uncontroversial while still letting everyone customise their own setup.
Learn from real teams
The Brewfiles uploaded here are a window into how real developers and teams structure their environments — which databases they run locally, which editor and launcher they standardise on, and which obscure CLI tools turn out to be widely loved. Browsing them is a fast way to refine your own team's baseline.
Build the shared file →
Generate, read, and maintain the Brewfile your team will depend on.
Pick the baseline tools →
A curated set of packages that make sensible defaults for a team Brewfile.