Homebrew on Linux is the portable package manager you didn’t know you needed, and its biggest strength is that it doesn’t try to be system-wide.

Let’s see it in action. Imagine you need jq, a lightweight and flexible command-line JSON processor, for a specific project. You don’t want to clutter your system’s global package manager (apt, dnf, etc.) with a tool that might only be relevant for this one task, or worse, conflict with system libraries.

First, you’ll install Homebrew itself. This isn’t like installing apt or dnf. Homebrew installs into your user’s home directory, typically ~/.linuxbrew.

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

This script will guide you through the process, asking for confirmation and potentially asking you to run a few commands to add Homebrew to your PATH.

Once installed, you’ll have a brew command available. Now, installing jq is as simple as:

brew install jq

This command doesn’t touch your system’s /usr/bin or /usr/local/bin. Instead, jq and its dependencies will be installed within ~/.linuxbrew/Cellar/jq/1.6/, and symlinks will be created in ~/.linuxbrew/bin. Because ~/.linuxbrew/bin is added to your PATH during installation, your shell will find this jq before any system-installed version.

This isolation is the core concept. Homebrew on Linux is designed to manage software within your user’s environment. It’s not a replacement for your distribution’s package manager, but a powerful complement for development tools, utilities, and libraries that you want to manage independently.

Think about the problems this solves. Developers often need specific versions of tools that might be older or newer than what their distribution provides. They might need multiple versions of the same tool for different projects. Homebrew excels here. You can install python@3.9 and python@3.11 side-by-side, and switch between them using brew switch python@3.9.

The internal mechanism is elegant. Homebrew uses "formulae," which are Ruby scripts that describe how to download, compile, and install a package. When you run brew install <formula>, Homebrew fetches the source, compiles it, and places the binaries and libraries into a versioned directory within ~/.linuxbrew/Cellar. It then creates symbolic links in ~/.linuxbrew/bin and ~/.linuxbrew/lib to make these installed packages available in your PATH and LD_LIBRARY_PATH, respectively.

The brew command is your primary interface. brew search <keyword> finds available packages. brew info <formula> shows details about a package, including its dependencies and installation location. brew uninstall <formula> removes it cleanly. brew upgrade updates all your installed Homebrew packages.

The real magic happens when you start managing multiple versions or complex development environments. For instance, if you’re working on a project that requires a specific version of Node.js, you can install it without affecting your system’s Node.js or other projects:

brew install node@16

Then, to use it, you’d typically add it to your shell’s PATH for that session or project:

eval "$(brew shellenv)" # This sets up PATH and other env vars for the current shell
node -v # Should show v16.x.x

This eval "$(brew shellenv)" command is crucial. It dynamically modifies your shell’s environment variables to prioritize Homebrew’s installations. Without it, your system might still find older or different versions of executables.

A common point of confusion is when Homebrew does interact with system libraries or when its own dependencies are missing. Homebrew tries to be self-contained, but sometimes it needs system libraries like zlib or openssl. On Linux, it often relies on your system’s package manager to provide these foundational libraries. If Homebrew fails to build a formula, check the error message carefully. It might indicate a missing development header (-dev package on Debian/Ubuntu, -devel on Fedora/CentOS) that Homebrew needs to compile against. For example, if brew install openssl fails, you might need to install libssl-dev on Ubuntu: sudo apt-get install libssl-dev.

The most surprising thing is how seamlessly Homebrew integrates into your existing shell environment without requiring root privileges for installation or package management. It achieves this by installing everything into your home directory and manipulating your PATH and other environment variables. This user-level isolation is its superpower, allowing for a clean, reproducible, and flexible way to manage your development tools.

The next step in mastering Homebrew is understanding how to create your own formulae or tap into third-party repositories for even more specialized software.

Want structured learning?

Take the full Homebrew course →