brew bundle: Install From a Brewfile in CI
brew bundle installs all the formulae, casks, and taps declared in a Brewfile, giving a repeatable toolchain.
A Brewfile is Homebrew's manifest, like a package.json for system tools. brew bundle makes CI install exactly the listed set.
What it does
brew bundle reads a Brewfile (a list of brew, cask, tap, and mas entries) and installs everything in it. brew bundle check reports whether all dependencies are already satisfied, useful as a fast gate.
Common usage
# Brewfile
# brew "jq"
# brew "node@20"
# cask "google-chrome"
export HOMEBREW_NO_AUTO_UPDATE=1
brew bundle install --file=Brewfile
# verify without installing
brew bundle check --file=BrewfileOptions
| Subcommand / Flag | What it does |
|---|---|
| install | Install everything in the Brewfile (default action) |
| check | Exit non-zero if any dependency is missing |
| --file=<path> | Use a Brewfile at a non-default path |
| cleanup | Uninstall anything not listed in the Brewfile |
| --no-lock | Do not write a Brewfile.lock.json |
In CI
Commit a Brewfile so every runner installs the same tools; run brew bundle check first to skip installs when the cache already satisfies it. Set HOMEBREW_NO_AUTO_UPDATE=1 so bundle does not re-fetch taps on each run.
Common errors in CI
"Error: Cannot find Brewfile" means --file points at the wrong path or the working directory is wrong. "Some casks failed to install" usually points at a cask needing a GUI or a licensed app not available on the runner. A bundle that reinstalls everything each run means HOMEBREW_NO_AUTO_UPDATE was not set and the tap keeps changing.