Reproducible Homebrew Packages with Brewfile
Declare and reproduce Homebrew packages with Brewfile. Learn brew bundle install, check, and cleanup with safety checks.
05 Sept 2025, 20:14 UTC

Desired outcome
You want a single text file that defines the Homebrew packages for a machine, a way to check whether the machine matches that file without changing anything, and a safe procedure to install missing packages or remove unlisted ones.
Prerequisites
- Homebrew installed and on your PATH. Run
brew --versionto confirm. - A terminal session as a normal user. Never run
brew bundlewithsudo; it can corrupt Homebrew prefix ownership and permissions. - Network access for formulae and casks that are not already cached.
- For Mac App Store entries, an Apple ID signed into the
mascommand-line tool may be required.
A formula is a Homebrew package definition. A cask is a macOS application distributed as a pre-built binary. A tap is a Git repository that contains additional formulae.
Create a Brewfile
Start with a project-specific file instead of overwriting your global ~/.Brewfile. This example installs two common command-line tools.
# /tmp/example.Brewfile
brew "git"
brew "tree"
You can add directives later:
tap "owner/repo"adds a third-party repository.cask "app-name"installs a macOS application.mas "App Name", id: 1234567890installs a Mac App Store app.
Verify the environment before applying
- Run
brew doctorand resolve warnings. It checks for permission problems, broken symlinks, and prefix issues. - Run
brew configand noteHOMEBREW_PREFIX,CPU, andOS. Formula availability differs by CPU architecture, so test the Brewfile on the same architecture where you plan to roll it out. - Confirm the subcommand exists:
brew bundle --versionorbrew bundle help.
Apply the Brewfile without guessing
- Run
brew bundle check --file=/tmp/example.Brewfile. It makes no changes. Exit code 0 means everything listed is already installed; a non-zero exit means something is missing. - Run
brew bundle install --file=/tmp/example.Brewfile. Homebrew installs missing formulae and taps automatically. - Confirm with
brew list git tree. Both tools should appear in the output.
Risks: brew bundle install changes system state. It may download software and require administrator authentication for casks. It does not uninstall packages you added manually unless you later run cleanup.
Check for drift and remove unlisted packages
Over time, you may install packages outside the Brewfile. To preview what would be removed:
brew bundle cleanup --file=/tmp/example.Brewfile --dry-run
Review the list, then run the same command without --dry-run only if you intend to delete those packages.
Recovery: If an installed formula breaks a workflow, remove it with brew uninstall <formula> or restore an earlier committed version of the Brewfile and re-run brew bundle install. There is no single brew bundle undo command.
Limitations
- Exact versions are not recorded by default. For stricter reproducibility, pin versions in the Brewfile or track Homebrew tap revisions in version control.
brew bundle cleanupcan remove packages not present in the file. Always runbrew bundle checkor--dry-runfirst.- Cask and
masoperations may require user interaction or credentials and are not always unattended. - Test the Brewfile on the target architecture before sharing it with a team.
Practical verification
After applying, run:
brew bundle check --file=/tmp/example.Brewfile && echo "Brewfile satisfied"
Then run brew doctor. If both return clean results, the machine matches the declared state.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.