What Homebrew Installs, and Where
Homebrew is a package manager for command-line tools. It downloads prebuilt binaries, called bottles, whenever a project publishes them, builds from source when it does not, and keeps everything it manages inside a single directory called the prefix:
- Apple silicon Macs (M-series):
/opt/homebrew - Intel Macs:
/usr/local
The formula metadata, the installed tools, and the symlinks that make those tools reachable all live under that prefix rather than in system directories. That one design choice explains most of what follows: because the prefix belongs to your user account, installing and updating software with brew never needs sudo. The main exception is a cask, which installs a macOS application bundle into /Applications instead of a Unix tool into the prefix.
If you are not sure where Homebrew lives on a machine that already has it, ask it:
brew --prefix
brew --repositoryBefore a first install, check three things:
- Your account can administer the Mac. The installer may ask for your password once while it creates the prefix directory.
- The Command Line Tools are present. If they are missing, the installer can trigger the macOS prompt for them, or you can start the installation yourself with
xcode-select --install. - You can reach the installer host and, later, the package hosts. Restricted networks are covered below.
Install Homebrew on Mac
To install brew on macOS, use the project's own installer script; the install takes no flags or options. The command below downloads that script and runs it in one step.
The widely copied form of this command pipes a URL straight into bash, which hides where the script comes from. The version here makes the same request with the scheme, host, and path on separate lines, so you can see exactly what you are about to execute:
HOMEBREW_INSTALL_SCHEME=https
HOMEBREW_INSTALL_HOST=raw.githubusercontent.com
HOMEBREW_INSTALL_PATH=/Homebrew/install/HEAD/install.sh
/bin/bash -c "$(curl -fsSL "${HOMEBREW_INSTALL_SCHEME}://${HOMEBREW_INSTALL_HOST}${HOMEBREW_INSTALL_PATH}")"Reading the command from the inside out:
curl -fsSLfetches the script over HTTPS. The-fflag fails on an HTTP error instead of feeding an error page to the shell, and-sSLfollows redirects quietly./bin/bash -cruns the fetched text as a script in a child shell. Nothing is saved to disk.HEADin the path means the current installer, not a pinned release. That is why verification is a required step later, not an optional one.- If those three variables do not match the host and path shown on the Homebrew homepage when you read this, stop and use the homepage version instead.
What you should see: the script prints a summary of what it will install and which directories it will change, waits for you to confirm, and may ask for your administrator password while it creates the prefix. It then clones Homebrew into the prefix and prints a Next steps block. That block is the part most people skip, and it is the part that wires up your shell.
Do not wrap the whole one-liner in sudo. Run it as your normal user and let the script decide when a single step needs elevated permissions; running it as root leaves root-owned files that break later updates.
Add brew to Your Shell PATH
The Next steps block contains two commands. The first appends one line to your shell profile; the second loads that line into the shell session you are using right now. The line itself calls a Homebrew helper:
/opt/homebrew/bin/brew shellenvbrew shellenv prints the environment Homebrew wants: it sets HOMEBREW_PREFIX, HOMEBREW_CELLAR, and HOMEBREW_REPOSITORY, prepends the prefix's bin and sbin directories to PATH, and adds the matching man and info paths. Wrapping it in eval applies those settings to the current shell. At this point you must use the full path, because brew alone is still not on your PATH; that is the problem you are fixing.
Apple silicon and Intel Macs differ only in that prefix path:
/opt/homebrew/bin/brew shellenv # Apple silicon
/usr/local/bin/brew shellenv # IntelFor zsh, the default login shell on macOS, add the line to ~/.zprofile:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.zprofileFor bash, use ~/.bash_profile instead:
echo 'eval "$(/opt/homebrew/bin/brew shellenv)"' >> ~/.bash_profileSwap /opt/homebrew for /usr/local in these commands if you are on an Intel Mac, then either open a new Terminal window or load the file in the current one:
eval "$(/opt/homebrew/bin/brew shellenv)"Two details cause most of the confusion that follows:
- Put the line in
~/.zprofile, not only in~/.zshrc. macOS Terminal starts login shells, so~/.zprofileis read by every new window, while~/.zshrcis read only by interactive shells and is skipped by some tools that launch commands on your behalf. - Import the environment instead of hand-writing a
PATHentry. The generated line also sets variables that some formulae and scripts expect, and it keeps working if the prefix moves.
To confirm the shell picked up the change, run echo $PATH and look for the prefix's bin directory ahead of /usr/bin.
Verify the Install
Open a new Terminal window, because profile files are read at startup and an old window still has the old environment. Then run three commands.
brew --version prints the version and the git revision it came from, for example Homebrew 4.x.y. This is the fastest check that PATH is correct: if the shell answers zsh: command not found: brew, the environment line is missing, is in the wrong file, or has not been loaded yet.
brew config prints the diagnostic dump. You do not need to read every line; check these:
HOMEBREW_PREFIXshould match where you installed Homebrew:/opt/homebrewor/usr/local.HOMEBREW_REPOSITORYshould point at the Homebrew checkout itself.- The
CLTline should name an installed Command Line Tools version. An empty or missing line means the tools are not installed. CPUtells you which architecture Homebrew is running under, and it should agree with the prefix. A prefix of/usr/localon an Apple silicon Mac usually means a second, Rosetta-based install.
brew doctor is the self-check. Your system is ready to brew. is the clean result. Anything else is a warning to read rather than an instruction to obey blindly: Homebrew is reporting what it found, and some findings are informational. Fix the warnings about permissions, unlinked tools, or missing Command Line Tools first.
For a smoke test, install one small formula and run it:
brew install jq
jq --versionThat is a completion check, not a lesson in using jq; using individual packages belongs in a different guide.
You are done when a new Terminal window can run brew, brew config shows the prefix you expect, and brew doctor reports a ready system.
Troubleshooting: command not found, Permissions, and Restricted Networks
zsh: command not found: brew
Work through this checklist in order:
- Run
which -a brew. No output means the prefix'sbindirectory is not onPATH. Two lines from two different prefixes, such as/opt/homebrew/bin/brewand/usr/local/bin/brew, mean two installs; see the note below. - Check which shell is running with
echo $SHELL. zsh reads~/.zprofilefor login shells and~/.zshrcfor interactive ones; bash reads~/.bash_profile. - Open the profile file and confirm the
evalline names the right prefix. A stray/usr/localin a line copied for an Apple silicon Mac is the most common cause. - Open a new Terminal window, or run
source ~/.zprofileto reload the file in place. A window that was already open when you edited the file keeps the old environment. - If you use a terminal inside an IDE, restart the IDE. Some of them start their own shells and keep their own environment.
Two prefixes on one Mac: if you moved from an Intel Mac, or once installed Homebrew under Rosetta, /usr/local/bin/brew and /opt/homebrew/bin/brew can both exist. Decide which one matches your Mac's architecture, make sure PATH points at it, and remove the other prefix with the uninstall steps later so updates stop landing in two places.
Permission errors
The rule is simple: never run brew with sudo. Homebrew is built to run as your user, and root-owned files inside the prefix or the caches break ordinary installs and updates afterwards. Running sudo brew install or sudo brew update is not a fix; it is the cause of the next failure.
If Homebrew reports that it cannot write somewhere, check who owns the prefix before changing anything:
ls -ld /opt/homebrew /opt/homebrew/bin
ls -ld /usr/local /usr/local/HomebrewIf those directories are owned by root, give them back to your account, using the prefix that brew --prefix printed:
sudo chown -R "$(whoami)" /opt/homebrewThen run brew doctor again. On Intel Macs, /usr/local may hold other software, so change only the Homebrew directories inside it, not the whole tree.
Restricted or corporate networks
Homebrew needs outbound HTTPS for two jobs: fetching the installer and the repository from GitHub, and fetching formula metadata and bottles from the package hosts. If a firewall allows only a fixed list of destinations, the installer or later installs fail at the fetch step.
- Behind an HTTP proxy, set
HTTPS_PROXY,HTTP_PROXY,ALL_PROXY, andNO_PROXYbefore running the installer, using thescheme://host:portform your network team provides. Bothcurlandgithonor those variables, so Homebrew takes the same route as your browser. - If your network mirrors Homebrew internally, point the tools at it:
HOMEBREW_BREW_GIT_REMOTEandHOMEBREW_CORE_GIT_REMOTEfor git remotes,HOMEBREW_API_DOMAINfor formula metadata, andHOMEBREW_BOTTLE_DOMAINfor prebuilt packages. Put those exports in the same profile file as yourshellenvline. - TLS interception that swaps certificates usually shows up as a certificate error from
curlorgitwhile the browser works fine. That is a network policy problem, not a Homebrew bug; use the proxy or mirror your network team provides. - On a slow or metered connection,
HOMEBREW_NO_AUTO_UPDATE=1skips the automatic update that runs before each install. Remove it on a normal connection so formulae stay current. - If the failure happened while downloading, nothing was installed. Fix the network settings and run the same command again; there is no partial state to clean up.
Install: Quick Recap
- Install: run the installer command and read the Next steps block it prints.
- Wire the shell: append
eval "$(<prefix>/bin/brew shellenv)"to~/.zprofilefor zsh or~/.bash_profilefor bash, then open a new Terminal window. - Verify:
brew --version, thenbrew configfor the prefix and Command Line Tools, thenbrew doctorfor a ready system. - When it fails: command not found means the
PATHline is missing or not loaded; permission errors mean the prefix is root-owned, and the fix is ownership, neversudo; fetch failures mean a proxy, mirror, or allowlist problem.
Uninstall Homebrew and Remove the Leftovers
If brew still runs, back up the package list first, because it is the one thing you cannot rebuild afterwards:
brew bundle dump --file=~/BrewfileHomebrew's repository ships an uninstall script at its root, so you can run the local copy without downloading anything:
brew --repository
bash "$(brew --repository)/uninstall.sh"The script lists the directories and files it will delete and asks for confirmation before it does anything. Let it finish, then close the window it ran in.
If brew no longer works, remove Homebrew by hand:
- Delete the
evalline from~/.zprofile,~/.bash_profile, and~/.zshrc. Leaving it behind means every new shell tries to load a path that no longer exists. - Delete the prefix. On Apple silicon that is one directory:
sudo rm -rf /opt/homebrewOn Intel Macs, /usr/local is shared with other software, so remove only Homebrew's directories and leave the rest of the tree alone:
sudo rm -rf /usr/local/Homebrew /usr/local/Cellar /usr/local/Caskroom /usr/local/FrameworksThe uninstall script is the safer route on Intel, because it also removes the symlinks Homebrew created in /usr/local/bin and /usr/local/opt and nothing else. Use brew --prefix to confirm the path first if you installed to a custom location.
- Remove the caches and the logs:
rm -rf ~/Library/Caches/Homebrew ~/Library/Logs/Homebrew- Check what is left.
which -a brewshould print nothing, andls -d /opt/homebrewshould report that the directory does not exist. - Handle casks separately. Applications installed with
brew install --caskare macOS app bundles in/Applications; the uninstall script removes Homebrew's records for them, but it does not always delete the app itself. Move anything you no longer want to the Trash.
The job is complete when new shells have no brew on PATH, the prefix directory is gone, and no Homebrew entry remains in your shell profile files.



