Skip to content
Latchkey

brew install and HOMEBREW_NO_AUTO_UPDATE in CI

brew install adds a formula or cask via Homebrew, and HOMEBREW_NO_AUTO_UPDATE stops it from re-fetching the tap on every call in CI.

Homebrew is the default package manager on macOS GitHub runners. Its auto-update behavior is convenient locally but wastes minutes and adds flakiness in CI.

What it does

brew install downloads and installs a formula (CLI tool or library) or a cask (macOS app). By default it first runs brew update to refresh the tap, which is slow in CI. Setting HOMEBREW_NO_AUTO_UPDATE=1 skips that refresh.

Common usage

Terminal
export HOMEBREW_NO_AUTO_UPDATE=1
export HOMEBREW_NO_INSTALL_CLEANUP=1
brew install jq
brew install --cask google-chrome
# pin to a tapped versioned formula
brew install node@20

Options

Flag / EnvWhat it does
HOMEBREW_NO_AUTO_UPDATE=1Skip the automatic brew update before install
HOMEBREW_NO_INSTALL_CLEANUP=1Skip post-install cleanup (faster, deterministic)
--caskInstall a cask (macOS application) instead of a formula
--quietReduce output noise in logs
formula@versionInstall a versioned formula, e.g. node@20

In CI

Set HOMEBREW_NO_AUTO_UPDATE=1 and HOMEBREW_NO_INSTALL_CLEANUP=1 to make brew installs faster and reproducible. Note the hosted macOS runners already have common tools; installing over a preinstalled formula can be slower than using what is there.

Common errors in CI

"Error: <formula> <version> is already installed" often means a preinstalled formula conflicts; use brew install --force or a versioned formula. "Error: Cannot install ... another version is already installed" needs brew link --overwrite. "fatal: not in a git directory" during auto-update points at a corrupted tap; that is exactly what HOMEBREW_NO_AUTO_UPDATE avoids. A download that fails with a 403 usually means a rate-limited GitHub token.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →