Jesse A. Green / notebook

Live demo: the DocCompiler guide library as a static, read-only snapshot (October 2026). No backend, no accounts, nothing to submit.

Homebrew User Guide

Generated June 2026 from Homebrew/brew at 5472a6b

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Homebrew is the missing package manager for macOS (or Linux). It installs the UNIX tools Apple didn't include with macOS, and software not packaged for your Linux distribution — all without needing sudo. You drive it entirely through one command: brew.

This guide covers everything you do as a Homebrew user: installing it, finding and installing software, keeping it up to date, managing GUI apps (casks) and background services, capturing your setup in a Brewfile, and fixing the problems you're most likely to hit. Architecture, the full environment-variable reference, internals, and contributor commands live in the companion Admin Guide.


Table of Contents

  1. Quick Start
  2. What Homebrew Is (and the words it uses)
  3. Installation
  4. Finding Software
  5. Installing Software
  6. Keeping Things Up to Date
  7. Removing Software & Reclaiming Disk Space
  8. Inspecting What's Installed
  9. GUI Apps with Homebrew Cask
  10. Background Services
  11. Reproducible Setups with a Brewfile
  12. Taps: Third-Party Repositories
  13. Shell Integration
  14. Advanced Usage
  15. Configuration You'll Actually Use
  16. Troubleshooting
  17. FAQ
  18. Command Reference

1. Quick Start

Install Homebrew, then install your first package:

# 1. Install Homebrew (macOS or Linux)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"

# 2. Install a package
brew install wget

# 3. Use it
wget --version

The everyday loop, once you're set up:

brew search node        # find it
brew install node       # install it
brew update             # refresh package definitions + Homebrew itself
brew outdated           # see what has newer versions
brew upgrade            # upgrade everything
brew uninstall node     # remove it

Tip

If you only remember one maintenance command, remember brew update && brew upgrade. The first refreshes Homebrew's knowledge of available versions; the second installs them.

Note

Homebrew runs as your normal user. It deliberately refuses to run under sudo — see Why Homebrew avoids sudo in the FAQ. The one exception is system-wide services (see Background Services).


2. What Homebrew Is (and the words it uses)

Homebrew installs packages into its own self-contained directory (the prefix) and then symlinks them into place so your shell can find them. Nothing is scattered across system directories, so everything Homebrew installs can be cleanly removed.

You'll meet this vocabulary constantly. Learn these eight terms and the rest of the docs read easily:

Term Meaning
formula A package definition that builds from upstream source (e.g. git, wget, python).
cask A package definition that installs pre-compiled binaries — typically a macOS GUI app (e.g. firefox, visual-studio-code).
bottle A pre-built binary version of a formula, poured into place instead of compiling from source. Most installs use bottles, so they're fast.
prefix Where Homebrew lives, e.g. /opt/homebrew (Apple Silicon), /usr/local (Intel Mac), /home/linuxbrew/.linuxbrew (Linux).
Cellar The directory holding every installed formula version, e.g. /opt/homebrew/Cellar.
keg One installed version of one formula, e.g. /opt/homebrew/Cellar/wget/1.25.0.
tap A Git repository of formulae, casks and/or commands. This is how third parties extend Homebrew.
keg-only A formula that is installed but not symlinked into the prefix (to avoid clashing with system tools).

A few more you'll see in command output: a rack is the Cellar/<name> directory containing one or more kegs; the opt prefix (opt/<name>) is a stable symlink to the active keg; the Caskroom is the cask equivalent of the Cellar; an external command is a brew subcommand defined outside the core project (see Taps).

Important

Formula vs. cask is the single most useful distinction. A formula is usually a command-line tool, built from source or poured from a bottle into the Cellar. A cask is usually a GUI application, installed as a ready-made binary into your /Applications folder and tracked in the Caskroom. Many commands accept --formula or --cask to disambiguate when a name exists as both.


3. Installation

Requirements

Platform Requirements
macOS A 64-bit Intel or Apple Silicon CPU; the latest version of macOS is best supported. The Xcode Command Line Tools are required (the installer offers to install them).
Linux A 64-bit x86_64 or ARM CPU, glibc 2.13+, plus gcc, make, and a few build basics. Homebrew installs into your home area and needs no root.

Install with the official script

The recommended installer works on both macOS and Linux:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
==> This script will install:
/opt/homebrew/bin/brew
...
==> Installation successful!

Warning

Install Homebrew in its default location. Bottles (the fast pre-built binaries) only work in the default prefix; install anywhere else and most formulae must be slowly compiled from source, which is unsupported. The default prefixes are /opt/homebrew (Apple Silicon), /usr/local (Intel Mac), and /home/linuxbrew/.linuxbrew (Linux).

Put brew on your PATH

On Linux, and on some macOS setups, the installer prints "Next Steps" telling you to add Homebrew to your shell. Do exactly what it says. The mechanism is brew shellenv, which prints the export lines to wire up PATH, MANPATH and INFOPATH:

zsh (macOS default)

echo 'eval "$(/opt/homebrew/bin/brew shellenv zsh)"' >> ~/.zprofile
eval "$(/opt/homebrew/bin/brew shellenv zsh)"

bash (Linux default)

echo 'eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"' >> ~/.bashrc
eval "$(/home/linuxbrew/.linuxbrew/bin/brew shellenv bash)"

fish

echo 'eval "$(/opt/homebrew/bin/brew shellenv fish)"' >> ~/.config/fish/config.fish
eval "$(/opt/homebrew/bin/brew shellenv fish)"

brew shellenv accepts bash, csh, fish, pwsh, sh, tcsh or zsh. If you omit the shell it tries to detect it, but naming it explicitly is more reliable.

Verify the install

brew --version
brew doctor
Your system is ready to brew.

Tip

brew doctor is your first stop whenever anything misbehaves. Its warnings are diagnostic hints for maintainers — if everything you use works, you can safely ignore them.

Uninstalling Homebrew

Homebrew is removed with a separate official script:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)"

4. Finding Software

Search by name

brew search wget

A bare substring matches formula names and cask tokens. Flank the term with slashes to use a regular expression, and the search is extended online to homebrew/core and homebrew/cask:

brew search /^node@/      # regex: every versioned node formula
brew search --cask figma  # casks only
brew search --formula jq  # formulae only

Search by description

brew search --desc "json processor"
brew desc --search "image resize"   # search names AND descriptions
brew desc wget                      # one-line description of a single package

Look at a specific package

brew info (alias abv) is how you decide whether to install something: it shows the version, what it depends on, its homepage, caveats, and whether it's already installed.

brew info node
==> node: stable 24.1.0 (bottled), HEAD
Platform built on Node.js
https://nodejs.org/
Not installed
From: https://github.com/Homebrew/homebrew-core/blob/HEAD/Formula/n/node.rb
==> Dependencies
Required: brotli ✘, c-ares ✘, icu4c ✘, libuv ✘, openssl@3 ✘

Useful brew info options:

Option Effect
--installed Inventory of everything you have installed. Add --json=v2 for machine-readable output.
--json JSON representation (use --json=v2 for formulae and casks).
--analytics Install/usage analytics for a package (see also --days 30|90|365).
--github Open the package's GitHub source page in a browser.
--sizes Show on-disk sizes of installed formulae and casks.

Other discovery commands:

brew formulae          # list every installable formula
brew casks             # list every installable cask
brew home node         # open the package's homepage in a browser
brew source node       # open the package's source repository in a browser

5. Installing Software

The basics

brew install wget                 # a formula (command-line tool)
brew install --cask firefox       # a cask (GUI app)
brew install git node wget        # several at once

If a name exists as both a formula and a cask, Homebrew installs the formula and warns you. Force the choice with --formula or --cask.

Note

By default brew install <formula> will also upgrade that formula if it's already installed but outdated, and will run brew cleanup afterwards. You can change both behaviours with environment variables — see Configuration.

What happens during an install

  1. Homebrew refreshes its package data (an "auto-update", at most once every 24 hours by default).
  2. It resolves and installs the package's dependencies.
  3. It pours a bottle (pre-built binary) if one exists for your OS — fast. Otherwise it compiles from source.
  4. It symlinks the result into the prefix so it's on your PATH.

Preview before committing

brew install --dry-run node     # show what would happen, change nothing
brew install --ask node         # print the plan, then prompt for confirmation

Tip

--ask (or setting HOMEBREW_ASK=1) is great for cautious installs: it prints the full dependency plan and only prompts when the plan pulls in more than what you named.

Common install options

Option What it does
-s, --build-from-source Compile from source even when a bottle exists.
--HEAD Install the latest unreleased ("main"/"trunk") version, if the formula defines one.
-f, --force Install without checking for existing keg-only or non-migrated versions; for casks, overwrite existing files.
-v, --verbose Print verification and post-install steps.
-d, --debug On build failure, drop into an interactive debugging shell in the build directory.
-n, --dry-run Show what would be installed without installing.
--only-dependencies Install just the dependencies, not the package itself.
--ignore-dependencies (Unsupported dev option) skip installing dependencies.
--display-times Print how long each package took.
--keep-tmp Keep the temporary build files.

Cask-specific install options include --adopt (adopt an already-present identical app instead of reinstalling), --skip-cask-deps, --require-sha, and --[no-]binaries. The --*dir options (e.g. --appdir, --fontdir) control where cask artifacts land — see GUI Apps.

Installing a specific version

Many tools publish versioned formulae:

brew install node@20      # a specific major version
brew install python@3.12

Run brew search /node@/ to see what versioned formulae exist for a given tool.


6. Keeping Things Up to Date

This is the workflow you'll run most often. There are three distinct steps and it helps to keep them straight:

brew update      # 1. refresh package definitions + Homebrew itself (no packages change)
brew outdated    # 2. list installed packages that have a newer version
brew upgrade     # 3. actually upgrade them

brew update

Fetches the newest formula/cask data and Homebrew itself from GitHub and runs any necessary migrations. It changes Homebrew's knowledge, not your installed packages.

brew update-if-needed is a fast, no-op-friendly variant for scripts: it only does work if an update is actually due.

brew outdated

brew outdated                 # everything with an update available
brew outdated --formula       # formulae only
brew outdated --cask          # casks only
brew outdated --greedy        # also include auto-updating casks normally skipped

brew upgrade

brew upgrade                  # upgrade all outdated, unpinned packages
brew upgrade node             # upgrade just one
brew upgrade --cask           # only outdated casks
brew upgrade --dry-run        # preview
brew upgrade --ask            # print the plan, then prompt (includes download sizes)

Important

Upgrading one package can upgrade many others. Homebrew only tests one combination of versions — the latest — so when you upgrade something, everything it depends on (and everything that depends on it) is brought up to date too. This is by design and keeps your system in a tested, supported state.

Holding a package back

Pin a package to stop brew upgrade from touching it:

brew pin node       # freeze node at its current version
brew upgrade        # node is now skipped
brew unpin node     # allow upgrades again

Warning

Pinning is a sharp tool. Other packages that need a newer version of a pinned formula may fail to install or run, because Homebrew won't build them against an outdated dependency. Prefer pinning only briefly. Pinned casks with auto_updates true may still update themselves through the app's own updater.

To stop Homebrew from even learning about new versions until you choose to:

export HOMEBREW_NO_AUTO_UPDATE=1

7. Removing Software & Reclaiming Disk Space

Uninstall a package

brew uninstall wget            # aliases: brew remove, brew rm
brew uninstall --force node    # remove ALL installed versions
brew uninstall --cask firefox  # remove a GUI app
brew uninstall --zap firefox   # cask: also remove its leftover files (use with care)

Caution

--zap removes all files associated with a cask, which may include files shared with other applications. --force deletes every installed version and ignores errors. Both are destructive — read what they'll remove before running them.

Remove things you no longer need

brew autoremove uninstalls formulae that were only ever installed as dependencies of something you've since removed:

brew autoremove --dry-run    # see what would be removed
brew autoremove              # remove unused dependencies

Clean the cache and old versions

brew cleanup                 # remove stale downloads + old versions of everything
brew cleanup --dry-run       # preview
brew cleanup node            # only for node
brew cleanup --prune=all     # remove ALL cached downloads
brew cleanup -s              # scrub the cache, even latest-version downloads

By default brew cleanup removes downloads older than 120 days; adjust with HOMEBREW_CLEANUP_MAX_AGE_DAYS. Homebrew also runs cleanup automatically after installs and every 30 days — disable that with HOMEBREW_NO_INSTALL_CLEANUP=1.

To see where downloads live:

brew --cache       # usually ~/Library/Caches/Homebrew on macOS

8. Inspecting What's Installed

List packages

brew list                       # everything installed (aliases: brew ls)
brew list --formula             # formulae only
brew list --cask                # casks only
brew list --versions            # with version numbers
brew list --versions node       # versions of one package
brew list node                  # the files inside node's keg

Filter by how things were installed:

Option Lists…
--installed-on-request Packages you asked for explicitly.
--installed-as-dependency Packages pulled in to satisfy others.
--poured-from-bottle Packages installed from a pre-built bottle.
--built-from-source Packages compiled locally.
--pinned Pinned packages only.
--multiple Only formulae with multiple versions installed.

Understand dependencies

brew deps node               # everything node depends on
brew deps --tree node        # as an indented tree
brew deps --installed        # dependencies of all installed formulae
brew uses --installed node   # installed packages that depend ON node
brew leaves                  # installed formulae nothing else depends on
brew missing                 # check for missing dependencies

Tip

brew leaves plus brew uses is the safe way to decide what you can remove. leaves shows the packages no other package needs; uses <formula> shows who would break if you removed <formula>.

Locate things

brew --prefix                # Homebrew's install root
brew --prefix node           # where node is installed
brew --cellar                # the Cellar path
brew --caskroom              # the Caskroom path
brew --repository            # Homebrew's own Git checkout
brew config                  # full system + Homebrew config (attach this to bug reports)
brew --version               # version numbers of brew + core taps

9. GUI Apps with Homebrew Cask

Casks install pre-built applications — usually macOS .app bundles — rather than building from source. Everything you learned about install, upgrade, uninstall and list works on casks; just add --cask where a name is ambiguous.

brew install --cask visual-studio-code
brew install --cask google-chrome firefox
brew upgrade --cask
brew uninstall --cask google-chrome
brew list --cask

Where cask artifacts go

By default macOS apps install into /Applications. Each artifact type has its own target directory, all of which you can override:

Option Default target
--appdir /Applications
--fontdir ~/Library/Fonts
--colorpickerdir ~/Library/ColorPickers
--prefpanedir ~/Library/PreferencePanes
--qlplugindir ~/Library/QuickLook
--screen-saverdir ~/Library/Screen Savers
--servicedir ~/Library/Services
--dictionarydir ~/Library/Dictionaries
--appimagedir ~/Applications (Linux AppImages)

(There are more, for input methods, audio/VST plugins, internet plugins, Spotlight importers and keyboard layouts.) Set them once and for all with HOMEBREW_CASK_OPTS:

export HOMEBREW_CASK_OPTS="--appdir=~/Applications --fontdir=/Library/Fonts"

--language picks a preferred language for casks that ship localized downloads, e.g. brew install --cask --language=de some-app.

Note

Some apps update themselves (via Sparkle or a built-in updater). Those casks are marked auto_updates true and are skipped by brew upgrade to avoid version conflicts — see the FAQ. Force them with brew upgrade --greedy or by naming the cask explicitly.


10. Background Services

brew services manages long-running background programs (databases, web servers, etc.) using macOS's launchctl or Linux's systemctl.

brew services list                 # show all managed services and their state
brew services start postgresql@16  # start now AND at login
brew services stop postgresql@16   # stop now and stop auto-starting
brew services restart postgresql@16
brew services run postgresql@16    # run now WITHOUT registering to auto-start
brew services info postgresql@16   # details about one service
brew services cleanup              # remove unused service files

Operate on everything at once with --all:

brew services stop --all

User services vs. system (boot) services

By default services run as you, starting at login, from ~/Library/LaunchAgents (macOS) or ~/.config/systemd/user (Linux).

Prefix with sudo to run a service system-wide, starting at boot, from /Library/LaunchDaemons (macOS) or /usr/lib/systemd/system (Linux):

sudo brew services start postgresql@16

Caution

Running services with sudo is the one place Homebrew intentionally uses elevated privileges. Only do this for services that genuinely must start at boot or run as a different user. When you sudo brew services start as root, Homebrew may take root ownership of some of the formula's paths and will warn you — those then require sudo rm to remove during upgrade/uninstall.

Handy flags: --file=<path> to start from a custom service file, --keep (with stop) to keep a service registered while stopping it, --no-wait/--max-wait=<secs> to control how long stop waits, and --json for machine-readable list/info output.


11. Reproducible Setups with a Brewfile

brew bundle records and restores your entire Homebrew setup from a single Brewfile — formulae, casks, taps, Mac App Store apps, and even VS Code extensions and several other package ecosystems. It's the right way to move to a new machine or keep a fleet consistent.

Capture your current setup

brew bundle dump                 # write a Brewfile in the current directory
brew bundle dump --global        # write to ~/.Brewfile
brew bundle dump --force         # overwrite an existing Brewfile
brew bundle dump --describe      # add a comment describing each entry

A Brewfile looks like:

tap "homebrew/cask-fonts"
brew "wget"
brew "node"
cask "firefox"
mas "Xcode", id: 497799835
vscode "ms-python.python"

Restore it

brew bundle install              # install everything in ./Brewfile
brew bundle --file=~/.Brewfile   # use a specific file
brew bundle upgrade              # install + upgrade outdated entries

Keep it tidy and check it

brew bundle list                 # list dependencies in the Brewfile
brew bundle check                # verify everything in the Brewfile is installed
brew bundle cleanup              # show what's installed but NOT in the Brewfile
brew bundle cleanup --force      # actually uninstall those extras
brew bundle add wget             # add an entry
brew bundle remove wget          # remove matching entries

Tip

brew bundle exec, brew bundle sh and brew bundle env run commands (or a shell) in an isolated environment containing only your Brewfile's dependencies. This is great for builds that must not accidentally pick up other installed software.

The Brewfile can be filtered to specific ecosystems on most subcommands with --formula, --cask, --tap, --mas, --vscode, --go, --cargo, --uv, --flatpak (Linux), --winget (WSL), --krew and --npm.


12. Taps: Third-Party Repositories

A tap is a Git repository of extra formulae, casks, and/or commands. Tapping one makes its packages installable as if they were built in. This is Homebrew's extension mechanism.

brew tap                              # list installed taps
brew tap user/repo                    # tap a GitHub repo (github.com/user/homebrew-repo)
brew tap user/repo https://...        # tap from any Git URL (SSH, GitLab, etc.)
brew install user/repo/formula        # install from a tap
brew untap user/repo                  # remove a tap
brew tap-info --installed             # details about installed taps

The one-argument form is a GitHub shortcut: brew tap user/repo clones https://github.com/user/homebrew-repo. The two-argument form accepts any URL and protocol Git understands.

Note

homebrew/core (formulae) and homebrew/cask (casks) are the official taps. By default Homebrew reads them from a fast JSON API rather than cloning them, so brew tap may not list them. To work with a local copy (needed to edit formulae yourself) set HOMEBREW_NO_INSTALL_FROM_API=1 and run brew tap --force homebrew/core.

Warning

Tapping a third-party repository means trusting its maintainers — its formulae run code on your machine. Homebrew is gaining a tap-trust system (brew trust, controlled by HOMEBREW_REQUIRE_TAP_TRUST); see the Admin Guide's Security section. Only tap repositories you trust.


13. Shell Integration

Tab completion

Homebrew ships completions for Bash, Zsh and Fish. They're enabled automatically when Homebrew is on your PATH via brew shellenv. To control whether Homebrew links completions provided by taps:

brew completions state    # show current state
brew completions link     # enable tap completions
brew completions unlink   # disable them

For Zsh, make sure Homebrew's completions directory is on your FPATH before compinit runs — brew shellenv handles this.

"Command not found" suggestions

When you run a command you don't have, Homebrew can suggest the formula that provides it. Set up the hook:

brew command-not-found-init   # prints the hook; add its output to your shell rc

You can also query it directly:

brew which-formula wget           # which formula provides `wget`
brew which-formula --explain wget # plus how to install it

Running tools without a permanent install

brew exec --formulae=jq,yq -- ./script.sh   # add jq + yq to PATH, run a script
brew exec cowsay "moo"                       # find/install a tool and run it

14. Advanced Usage

Linking creates the symlinks from a keg into the prefix; it happens automatically on install but you can do it by hand:

brew unlink node          # remove node's symlinks (temporarily disable it)
brew link node            # restore them
brew link --overwrite node  # overwrite conflicting files while linking
brew link --dry-run node    # preview

This is the standard trick for switching between versioned formulae, e.g. brew unlink node && brew link node@20.

Keg-only formulae

Some formulae (often ones that would shadow macOS-provided tools) are installed keg-only: present in the Cellar but not symlinked onto your PATH. brew info <formula> explains why and prints the PATH/PKG_CONFIG_PATH exports you need to use it. You can force it onto your PATH with brew link --force <formula>, but that may shadow system software.

Build from source / bleeding edge

brew install --build-from-source wget   # compile rather than pour a bottle
brew install --HEAD some-formula        # install the latest unreleased code
brew reinstall --build-from-source wget # rebuild from source

Fetch without installing

brew fetch node            # download the bottle/source (and print checksums)
brew fetch --deps node     # also fetch dependencies
brew fetch --HEAD node     # fetch the HEAD version

History and logs

brew log node              # git log for a formula
brew log -p node           # with patches
brew gist-logs node        # upload a failed build's logs to a Gist for a bug report

15. Configuration You'll Actually Use

Homebrew is configured through HOMEBREW_* environment variables. Set them in your shell profile (~/.zshrc, ~/.bash_profile, etc.). Variables must have a value — use export HOMEBREW_NO_AUTO_UPDATE=1, not a bare export.

These are the ones users reach for most often. The complete ~110-variable reference is in the Admin Guide.

Variable Effect
HOMEBREW_NO_AUTO_UPDATE Don't auto-run brew update before installs/upgrades.
HOMEBREW_AUTO_UPDATE_SECS Minimum seconds between auto-updates (default 86400 = 24h).
HOMEBREW_NO_INSTALL_CLEANUP Don't auto-cleanup after installs or every 30 days.
HOMEBREW_NO_CLEANUP_FORMULAE Comma-separated formulae to exclude from cleanup/autoremove.
HOMEBREW_CLEANUP_MAX_AGE_DAYS Age threshold for cached-download cleanup (default 120).
HOMEBREW_NO_ANALYTICS Disable anonymous usage analytics.
HOMEBREW_NO_EMOJI Don't print the 🍺 on a successful build.
HOMEBREW_NO_COLOR Disable coloured output.
HOMEBREW_CASK_OPTS Default options for all cask commands, e.g. --appdir=~/Applications.
HOMEBREW_EDITOR Editor for brew edit (falls back to $EDITOR/$VISUAL).
HOMEBREW_CACHE Override the download-cache directory.
HOMEBREW_NO_INSTALL_UPGRADE brew install <x> won't upgrade <x> if it's already installed but outdated.
HOMEBREW_ASK Default to --ask (preview + confirm) on install/upgrade/reinstall.
HOMEBREW_DOWNLOAD_CONCURRENCY Parallel download connections (auto = 2× CPU cores; 1 = serial).
HOMEBREW_MAKE_JOBS Parallel build jobs (default = CPU cores).

Behind a proxy, Homebrew honours the standard http_proxy, https_proxy, all_proxy, ftp_proxy and no_proxy variables for its curl/git/svn downloads.

export HTTPS_PROXY=http://proxy.example.com:8080

Note

brew analytics controls usage analytics interactively: brew analytics off turns them off (equivalent to HOMEBREW_NO_ANALYTICS=1), brew analytics state shows the current setting. Read more at https://docs.brew.sh/Analytics.


16. Troubleshooting

Important

Before anything else, run brew update and brew doctor. Most problems are already fixed upstream or flagged by the doctor. When you file a bug, include the output of brew config and brew doctor.

Error: brew complains about absence of "Command Line Tools"

Cause: On macOS, the Xcode Command Line Tools aren't installed. Solution: Run xcode-select --install in the terminal and follow the prompts. Prevention: Reinstall them after every major macOS upgrade (see below).

Error: build failures after upgrading macOS

Symptoms after a macOS upgrade look like dyld: Library not loaded: /opt/homebrew/opt/icu4c/lib/libicui18n.76.dylib or configure: error: Cannot find libz.

Cause: A macOS upgrade invalidates the old Command Line Tools and some built binaries. Solution:

xcode-select --install
brew upgrade

Error: brew update complains about untracked working tree files

Cause: A long-since-fixed bug left stray files in Homebrew's Git checkout. Solution:

cd "$(brew --repository)"
git reset --hard FETCH_HEAD
# if brew doctor still complains:
cd "$(brew --repository)/Library"
git clean -fd
Warning: Could not link <formula>. Unlinking...
Error: The `brew link` step did not complete successfully

Cause: A file Homebrew wants to symlink already exists in the prefix (often left by a non-Homebrew install). Solution: Inspect the listed conflicting files. If you're sure they're safe to replace:

brew link --overwrite --dry-run <formula>   # list what would be deleted
brew link --overwrite <formula>             # do it

Error: cask download fails with a cURL error

Cause: Most often a stray ~/.curlrc, an outdated cask URL, or a network/vendor problem. Solution: Check for and remove a ~/.curlrc (ls -A ~ | grep .curlrc) and retry. If the vendor's own download link (brew home <cask>) also fails, the problem is upstream, not Homebrew. If the link works but the cask doesn't, the cask is outdated — consider submitting a fix.

Error: cask "permission denied" writing to /Applications

Cause: Your account lacks write access to /Applications, or the Caskroom isn't owned by you. Solution: Install to a writable directory with --appdir=~/Applications, or fix Caskroom ownership:

sudo chown -R "$(whoami)" "$(brew --caskroom)"

Cask apps lose their Dock/Launchpad position or permissions after upgrade

Cause: Without "App Management" or "Full Disk Access" permission, Homebrew falls back to uninstall-then-reinstall, which makes macOS forget the app's metadata. Solution: Grant your terminal app App Management or Full Disk Access in System Settings → Privacy & Security. Homebrew then does in-place upgrades that preserve metadata.

Two Homebrew installations (after Migration Assistant)

Cause: Migration Assistant copied an Intel Mac's /usr/local Homebrew onto an Apple Silicon Mac, which should use /opt/homebrew. Solution: Verify your terminal runs in arm64 mode (arch prints arm64), reinstall Homebrew under /opt/homebrew, restore your packages with brew bundle, then uninstall the old /usr/local install. The full procedure is in Homebrew's Common Issues docs.

My GUI apps can't find Homebrew tools

Cause: macOS GUI apps don't inherit your shell's PATH. Solution:

sudo launchctl config user path "$(brew --prefix)/bin:${PATH}"
# then reboot

Nothing here matches

brew doctor                 # diagnose
brew config                 # gather system info for a report
brew gist-logs <formula>    # share a failed build's logs

If a totally broken install can't be repaired, the cleanest reset is to brew bundle dump, uninstall Homebrew, reinstall it, and brew bundle install.


17. FAQ

Q: How do I update everything? Run brew update (refresh definitions), then brew outdated (see what's old), then brew upgrade (upgrade it). Upgrade one package with brew upgrade <formula>.

Q: How do I stop a formula from being upgraded? brew pin <formula>. Allow it again with brew unpin <formula>. To stop Homebrew from even learning about new versions, export HOMEBREW_NO_AUTO_UPDATE=1.

Q: How do I keep old versions when upgrading? By default Homebrew removes old versions on upgrade and during periodic cleanup. Disable that with export HOMEBREW_NO_INSTALL_CLEANUP=1 (or per-package with HOMEBREW_NO_CLEANUP_FORMULAE=foo,bar).

Q: Where does Homebrew download things? brew --cache (usually ~/Library/Caches/Homebrew on macOS).

Q: Why does installing one thing upgrade a bunch of others? Homebrew only tests the latest combination of all package versions, so a dependency upgrade can cascade. This keeps your system in a supported state.

Q: Why does Homebrew refuse to run under sudo? Build scripts run arbitrary code; running them as root would let a malicious or buggy build modify anything on your system. Homebrew installs into a user-owned prefix specifically so sudo is unnecessary. (System-wide services are the deliberate exception, and even then only the service runs elevated.)

Q: What does "keg-only" mean? The formula is installed into the Cellar but not symlinked into the prefix, usually to avoid shadowing a macOS-provided tool. brew info <formula> explains why and how to put it on your PATH.

Q: Why aren't some cask apps upgraded by brew upgrade? Apps that update themselves are marked auto_updates true and skipped to avoid version conflicts. Upgrade them explicitly with brew upgrade <cask> or brew upgrade --greedy, or set HOMEBREW_UPGRADE_AUTO_UPDATES_CASKS=1.

Q: Can I edit formulae myself? Yes. Set HOMEBREW_NO_INSTALL_FROM_API=1, run brew tap --force homebrew/core to get a local copy, then brew edit <formula>. brew update will even merge your edits with upstream. Undo all local changes with brew update-reset.

Q: Why can't I open a Mac app from an "unidentified developer"? That's Apple's Gatekeeper, not Homebrew. Right-click the app, choose Open, and confirm — only for apps you trust. Leave system-wide protection on.

Q: Why isn't a particular brew command documented in man brew? It's probably an external command from a tap; run brew <command> --help.

Q: How do I completely uninstall Homebrew? Run the official uninstall script: /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/uninstall.sh)".


18. Command Reference

Get help for any command with brew help <command> or brew <command> --help. man brew has the complete manual.

Global options

These work across most commands and must appear after the command name (e.g. brew install -v node):

Option Meaning
-d, --debug Display debugging information (and, on build failure, open a debug shell).
-q, --quiet Make output more quiet.
-v, --verbose Make output more verbose.
-h, --help Show help for the command.

Installing & removing

Command Purpose
install Install a formula or cask.
reinstall Uninstall and reinstall with the same options.
uninstall (remove, rm) Remove a formula or cask.
autoremove Remove no-longer-needed dependencies.
pin / unpin Prevent / allow upgrades of a package.
link (ln) / unlink Add / remove a formula's symlinks in the prefix.
fetch Download a package (and dependencies) without installing.
postinstall Re-run a formula's post-install steps.

Updating

Command Purpose
update (up) Refresh Homebrew and all package definitions.
update-if-needed Update only if due (script-friendly).
outdated List packages with newer versions available.
upgrade Upgrade outdated, unpinned packages.
update-reset Hard-reset Homebrew's Git repos to upstream (destroys local changes).
migrate Migrate renamed packages to their new names.

Discovering & inspecting

Command Purpose
search (-S) Substring/regex search of names and tokens (extends online).
info (abv) Show details about a package or your install.
desc Show / search one-line descriptions.
home (homepage) / source Open a package's homepage / source repo in a browser.
list (ls) List installed packages (or a keg's files).
deps / uses Show dependencies / dependents of a formula.
leaves List formulae nothing depends on.
missing Check for missing dependencies.
options Show a formula's install options.
formulae / casks List all installable formulae / casks.
log Show a package's git log.
config (--config) Show Homebrew + system configuration.
doctor (dr) Diagnose potential problems.
--prefix / --cellar / --caskroom / --cache / --repository / --version Show key paths and versions.

Casks, services, bundles & taps

Command Purpose
bundle Manage a Brewfile (dump, install, upgrade, check, cleanup, add, remove, list, exec, sh, env).
services Manage background services (list, start, stop, restart, run, kill, info, cleanup).
tap / untap Add / remove a third-party repository.
tap-info Show details about taps.
trust / untrust Trust / untrust a non-official tap, formula, cask or command.

Shell & environment

Command Purpose
shellenv Print export lines to add Homebrew to your shell.
completions Control linking of tap shell completions.
command-not-found-init Print the "command not found" hook.
which-formula Find which formula provides a command.
exec (x) Run a command in a Homebrew-populated environment.
analytics View / toggle anonymous usage analytics.
developer Toggle Homebrew's developer mode.
commands / command List commands / show a command's file path.
help Show usage for a command.

Note

Homebrew also has ~60 developer commands (audit, create, edit, bump-formula-pr, style, test, livecheck, and more) for people who write and maintain formulae. Those are documented in the Admin Guide, which also carries the complete HOMEBREW_* environment-variable reference, Homebrew's architecture, and its security model.