# Homebrew User Guide

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](#1-quick-start)
2. [What Homebrew Is (and the words it uses)](#2-what-homebrew-is-and-the-words-it-uses)
3. [Installation](#3-installation)
4. [Finding Software](#4-finding-software)
5. [Installing Software](#5-installing-software)
6. [Keeping Things Up to Date](#6-keeping-things-up-to-date)
7. [Removing Software & Reclaiming Disk Space](#7-removing-software--reclaiming-disk-space)
8. [Inspecting What's Installed](#8-inspecting-whats-installed)
9. [GUI Apps with Homebrew Cask](#9-gui-apps-with-homebrew-cask)
10. [Background Services](#10-background-services)
11. [Reproducible Setups with a Brewfile](#11-reproducible-setups-with-a-brewfile)
12. [Taps: Third-Party Repositories](#12-taps-third-party-repositories)
13. [Shell Integration](#13-shell-integration)
14. [Advanced Usage](#14-advanced-usage)
15. [Configuration You'll Actually Use](#15-configuration-youll-actually-use)
16. [Troubleshooting](#16-troubleshooting)
17. [FAQ](#17-faq)
18. [Command Reference](#18-command-reference)

---

## 1. Quick Start

Install Homebrew, then install your first package:

```bash
# 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:

```bash
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`](#why-does-homebrew-refuse-to-run-under-sudo) in the FAQ. The one exception is system-wide services (see [Background Services](#10-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](#12-taps-third-party-repositories)).

> [!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:

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

```text
==> 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)"

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

=== "bash (Linux default)"

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

=== "fish"

    ```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

```bash
brew --version
brew doctor
```

```text
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:

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

---

## 4. Finding Software

### Search by name

```bash
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`:

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

### Search by description

```bash
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.

```bash
brew info node
```

```text
==> 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:

```bash
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

```bash
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](#15-configuration-youll-actually-use).

### 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

```bash
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](#9-gui-apps-with-homebrew-cask).

### Installing a specific version

Many tools publish versioned formulae:

```bash
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:

```bash
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`

```bash
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`

```bash
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:

```bash
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:

```bash
export HOMEBREW_NO_AUTO_UPDATE=1
```

---

## 7. Removing Software & Reclaiming Disk Space

### Uninstall a package

```bash
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:

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

### Clean the cache and old versions

```bash
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:

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

---

## 8. Inspecting What's Installed

### List packages

```bash
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

```bash
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

```bash
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.

```bash
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`:

```bash
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](#why-arent-some-cask-apps-upgraded). 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`.

```bash
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`:

```bash
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):

```bash
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

```bash
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:

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

### Restore it

```bash
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

```bash
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.

```bash
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*:

```bash
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:

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

You can also query it directly:

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

### Running tools without a permanent install

```bash
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

### Link and unlink

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

```bash
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

```bash
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

```bash
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

```bash
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.

```bash
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:**

```bash
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:**

```bash
cd "$(brew --repository)"
git reset --hard FETCH_HEAD
# if brew doctor still complains:
cd "$(brew --repository)/Library"
git clean -fd
```

### Error: `Could not link <formula> ... Target ... already exists`

```text
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:

```bash
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:

```bash
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:**

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

### Nothing here matches

```bash
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](#12-taps-third-party-repositories) 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.

---

_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. Unofficial; not affiliated with or reviewed by the project._
