You can have multiple versions of a Homebrew package installed, but only one can be active at a time. Here’s how to switch between them.

Let’s say you have node installed, and you want to switch from version 16.14.0 to a newer 18.17.0 that you’ve also installed.

First, check which versions are installed:

brew list --versions node

This will output something like:

node 16.14.0 18.17.0

To see which version is currently active, run:

brew info node

The output will highlight the currently linked version. For example:

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.
...
/usr/local/Cellar/node/16.14.0 (1,961 files, 44.9MB) *
/usr/local/Cellar/node/18.17.0 (2,101 files, 51.8MB)

The asterisk * indicates the active version.

To switch to a different installed version, you use brew switch. The syntax is brew switch <formula> <version>.

So, to switch to 18.17.0:

brew switch node 18.17.0

Homebrew will then perform the switch by unlinking the old version and linking the new one. It’s essentially a sophisticated form of symbolic linking within the Homebrew prefix. The Cellar directory (/usr/local/Cellar or /opt/homebrew/Cellar on Apple Silicon) holds all installed versions, and brew switch manipulates the symlinks in the main Homebrew prefix (/usr/local or /opt/homebrew) to point to the desired version’s directory in the Cellar.

After running the switch command, verify the change:

brew info node

You should now see the asterisk next to 18.17.0.

Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine.
...
/usr/local/Cellar/node/16.14.0 (1,961 files, 44.9MB)
/usr/local/Cellar/node/18.17.0 (2,101 files, 51.8MB) *

If you want to remove an older version you no longer need, use brew uninstall <formula>@<version> or brew uninstall --force <formula>@<version> if there are issues. For example, to remove the 16.14.0 version:

brew uninstall node@16.14.0

However, brew switch is the command to manage active versions. You might also see brew link and brew unlink, which are more granular operations. brew switch is a convenience command that performs both unlink and link for you.

The actual mechanism involves updating symbolic links in your Homebrew installation’s main directory (e.g., /usr/local/opt/node or /opt/homebrew/opt/node) to point to the specific version’s directory within the Cellar. This ensures that when you run node from your terminal, you’re executing the binaries of the version you’ve switched to.

This capability is incredibly useful for testing software against different library versions or for managing dependencies that have conflicting requirements. It allows you to isolate environments for specific projects without resorting to complex virtual machine setups for simple version conflicts.

When you install a new version of a formula that’s already installed, Homebrew doesn’t automatically switch to it. It simply adds the new version to the Cellar and keeps the currently active version linked. You must explicitly tell Homebrew which version you want to use as the active one.

Homebrew also has a concept of "kegs," which are the individual versioned directories within the Cellar. brew switch essentially moves the "keg-only" symlink for the formula.

The next thing you’ll likely encounter is managing a formula that has complex dependencies, where switching versions of one formula might require careful consideration of its dependents.

Want structured learning?

Take the full Homebrew course →