How to Install Software via Homebrew

Installing software is a pain in the ass—especially when you need to set up everything from scratch after you got a new computer. Not only do you have to visit each and every of your application’s website, where you then need to navigate to the Download section and find the right download link for your operating system, only to wait for the download to finish before you can finally unzip it and move the app to the /Applications folder. This tedious procedure cries out for automation.

Wouldn’t it be a lot easier if you just needed to tell your computer which application you want to install and your computer would then go ahead, automatically figure out everything else by itself so that in the end your software magically appears in your /Applications folder without you doing anything? Exactly this is the purpose of so-called package managers such as Homebrew.

Installing the Xcode Command Line Tools

You need to make sure that you have the Xcode Command Line Tools installed before you can start using Homebrew to install software. Installing them is easy. In fact, there are two different ways to get them. The Command Line Tools are necessary because they contain the compiler collection GCC and Homebrew does not function without GCC.

The More Common Way

The easier way to get the Xcode Command Line Tools is to first install Xcode from the Mac App Store. You then need to agree to its End User License Agreement (EULA). When you open Xcode for the first time, the EULA pops up. Simply click on “Accept” and close Xcode again.

Alternatively, you could accept the EULA by running this terminal command:

sudo xcodebuild -license accept

After you’ve accepted Xcode’s EULA, you can finally install the Xcode Command Line Tools:

xcode-select --install

A pop-up will then ask whether you want to install the Xcode Command Line Tools. Confirm the dialog by clicking on “Install”.

Alternative Option

In case you don’t want to install Xcode because you can’t spare 4 GB of disc space, you could also visit the Apple Developer site and sign up for a free Developer Account if you don’t have one. This has nothing to do with the paid Developer Account. Unless you don’t want to e.g. submit iOS apps to the App Store, you don’t have to pay anything. After you log in with your Apple ID, you can download the Xcode Command Line Tools from the Downloads Section.

Installing Homebrew

Now that the Xcode Command Line Tools are installed, you can continue to install Homebrew with this command:

/usr/bin/ruby -e "$(curl -fsSL"

That’s it! Now you’ve got Homebrew on your system :sunglasses: To ensure that everything went well, you could enter brew doctor into the terminal.

Adjusting the PATH Variable

In the last step, we used Ruby—which is pre-installed on every Mac by default—to load Homebrew from its GitHub repository and install it.

The problem with this pre-installed version of Ruby is that it is not the newest version and very outdated, like most other tools pre-installed by Apple. We really should update it. Of course, now we can use Homebrew to do that. That’s the reason we’ve installed Homebrew in the first place, right?

The leads us to the next problem; these system-provided versions of Ruby, Python, virtually every pre-installed tool can neither be updated nor modified nor deleted by us users. They are protected by the operating system. That’s perfectly fine, because that ensures that we don’t accidentally break our machine and macOS keeps functioning in case we ever try to delete one of these programs because we assume we don’t need them anymore.

Instead, we’re going to install a second copy of Ruby, which co-exists next to the system’s version. With this version we can do what we want and it is much easier to maintain. However, this poses the question which of these two versions should be executed when we call ruby. The system’s version because it was there first? Or the new one, because it is more recent? How does the system know which one should be executed?

The answer is the so-called PATH variable. This variable contains a list of locations where software is installed. The order of this list determines where the operating systems looks first. If we want to use the more recent and maintainable versions we’ve installed ourselves, then we need to change the order so that the folder for user-installed applications comes before the folder for pre-installed software. If the system can’t find the specified application there, it looks in the next folder… and if it didn’t find the program there either, it looks in the next folder, and so on. To change this list to the right order, you need to enter this command into the terminal:

echo export PATH='/usr/local/bin:$PATH' >> ~/.profile

This will specifically tell macOS to look for a program in the directory /usr/local/bin (the place where Homebrew installs its stuff) before it looks anywhere else. Basically, the PATH variable is a list of folders that are separated by a colon (:). So we simply prepended /usr/local/bin to the already existing content of that variable. Only in case macOS couldn’t find the program in the first folder it would continue to look in the following directories as a fallback.

To test if the PATH variable is set correctly, run these two commands:

source ~/.profile
echo $PATH

This reloads the file containing the PATH variable, so that the changes take effect (alternatively, you could also close and re-open your terminal window) and then outputs the current value of the variable. It should look like this: /usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin

It doesn’t matter if your output looks slightly different or if a folder appears multiple times or if /usr/local/bin appears both before and after /usr/bin. The only important thing is that there is no /usr/bin (the place where all the pre-installed software lives) coming before /usr/local/bin, since in that case macOS would stop looking for the version we’ve installed ourselves once it found the pre-installed version.

Installing Your Applications

Now that everything is set up correctly, we can finally begin to actually install programs. To install an application via Homebrew, we first need to know it’s “identifier”. We can either google it or search for it using brew search followed by the program, e.g. brew search ruby. In most cases the identifier is the application name, ruby in this case. There are exceptions, however, usually when there are multiple versions of the same program available for compatibility reasons (e.g. brew install python vs brew install python@2).

The syntax is pretty straight forward. You may either install applications individually…

brew install ruby
brew install bash
brew install git

…or all together:

brew install ruby bash git

In case this doesn’t work on your machine, the PATH variable probably hasn’t been adjusted correctly during the last step. I configured my machine to use the file ~/.profile, but in case you’ve tinkered around with these kind of files before, you might use ~/.bash_profile instead. If you’re not sure or don’t know what all this means, please follow my instructions in this post about these so-called dotfiles.

Note: if you’re working with Python regularly, brew install python is not the preferred way to install Python. There is a far more practical solution. Definitely check out my other post on how to set up your Python environment for scientific computing if you want to read more.

Homebrew Cask: For Applications With a Graphical User Interface

Homebrew itself is rather useful for developer and command line tools. To install apps with a Graphical User Interface, like a web browser or Spotify, you’ll need a slightly different syntax: brew cask install.

Here are a few examples which apps you might want to install using Homebrew Cask:

brew cask install google-chrome
brew cask install 1password
brew cask install spotify
brew cask install vlc
brew cask install sublime-text
brew cask install skype
brew cask install evernote
brew cask install java
brew cask install intellij-idea-ce

If you want to know which other useful apps I have installed on my Mac, you can read about my personal setup here.

Updating Applications and Maintaining the Cellar

Let me tell you just one last thing about how Homebrew works. In case you’re wondering where your applications get installed to: GUI apps installed via Homebrew are moved to the /Applications folder just like you did it all the time. And your command line tools live deep in the system in the /usr/local/bin directory. That’s at least the place where other programs are looking for them and a historic UNIX convention one should follow if one doesn’t want to break things. Remember why we needed to change the PATH variable? Exactly for this reason! Because Homebrew installs its stuff into /usr/local/bin—according to the convention—and we want to look there first, before we use the system-provided versions which live in /usr/bin. That’s why /usr/local/bin has to be the leftmost entry in the colon-separated list the PATH variable is.

However, Homebrew doesn’t place your programs directly into the /usr/local/bin folder. Instead, it uses a smart trick called symlinking. Homebrew maintains it’s own subdirectory which is called the Cellar. All the software you install via Homebrew gets installed into that directory first. And then Homebrew creates a link in the /usr/local/bin folder, pointing to the newest versions in the Cellar. This symlink creates some sort of virtual copy.

But why is Homebrew doing this you ask? Why isn’t it installing the programs directly into /usr/local/bin? Imagine downlading an update for one of your programs. And after a while another one. And another one. Eventually the /usr/local/bin directory will be pretty crammed with multiple outdated versions of the same app. With the symlink method, you’ll only ever have one version in this important directory, and it’s always the newest one. And when you download an update, Homebrew only need’s to change the link to point to the newer version.

But this doesn’t really solve the problem! It’s just a different folder now! Yes, that’s true. But Homebrew isn’t the only one installing software in the /usr/local/bin directory. You yourself could write and copy files into that folder (which I don’t recommend). By keeping all its stuff in its own folder, Homebrew keeps out of the way and avoids conflicts and overriding. And for cleaning up the Cellar and deleting all the outdated versions there’s also a handy command:

brew cleanup

So I was talking about updating apps. How do you do that? Generally, before installing a new app or doing an update, it’s always a good idea to update Homebrew’s internal list of available programs, so that it knows the newest version available for each app (and to update Homebrew itself). This command only updates the internal list of Homebrew (aka the formulae), not your apps. To update your actual apps installed via Homebrew, you need an additional command (Homebrew calls this “upgrade”). You can combine both commands to brew update && brew upgrade. In more recent versions of Homebrew, the brew update part will be performed automatically and is not necessary anymore. It’s sufficient to type:

brew upgrade

This downloads possibly available updates for all of your apps into the mentioned Cellar without deleting the current version. Depending on how many updates there are available, this can easily take up several hundreds of megabytes worth of disk space, so don’t forget to perform a cleanup after each time you upgraded your apps.

To update your casks, you need a slightly different command. Instead of brew upgrade you have to use brew cask upgrade, since Homebrew (at least at the moment) doesn’t understand that there’s a new version available for you app, even though brew update just fetched the latest version numbers. The Cask team is working on it however.

What I don’t like about brew cask upgrade is that it upgrades all my apps. There are some cases where I deliberately want to stay on an older version, because the developers switched to a subscription business model or the new features are simply not worth the upgrade price. With brew cask upgrade you would upgrade those apps too. What you can do instead is to update your apps via their own update mechanism or update them individually using this command:

brew cask reinstall <identifier>

Just remember to do your brew cask cleanup after you’re finished upgrading to remove the downloaded installers.

That’s it so far. Hope you find this helpful. If you do, why don’t you let me know in the comments :blush: Cheers!