Skip to content
Latchkey

brew install: Usage, Options & Common CI Errors

brew install adds command-line tools and apps via Homebrew on macOS (and Linux) runners.

Homebrew is the default package manager on macOS CI runners. The CI pain points are its slow auto-update step and non-zero exits when something is already installed.

What it does

brew install downloads and installs a formula (CLI tool) or, with --cask, a GUI app. On macOS runners (GitHub Actions, etc.) Homebrew is preinstalled. By default brew updates itself before installing, which adds latency you often want to suppress in CI.

Common usage

Terminal
brew install jq
HOMEBREW_NO_AUTO_UPDATE=1 brew install jq      # skip the slow self-update
brew install --cask google-chrome
brew install node@20                            # versioned formula
brew list --versions jq || brew install jq      # idempotent guard

Common errors in CI

brew install exits non-zero with "Warning: jq 1.7 is already installed" on a runner that already has it - guard with brew list --versions X || brew install X, or use brew install X || true. The biggest time sink is the implicit brew update; set HOMEBREW_NO_AUTO_UPDATE=1 to skip it. "Error: Cannot install ... the bottle needs to be built from source" means no prebuilt binary for that OS version - slow, and sometimes needs Xcode CLT (xcode-select --install).

Options

Flag / envWhat it does
--caskInstall a GUI app instead of a formula
HOMEBREW_NO_AUTO_UPDATE=1Skip the self-update before install
--quietLess output
list --versions <pkg>Check if/what version is installed
HOMEBREW_NO_INSTALL_CLEANUP=1Skip post-install cleanup

Related guides

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