In my quest to "automate all the things," I have been on a journey to manage my Mac laptop as the code it inherently is. Instead of pointing and clicking to manually manage my applications and utilities, I prefer to use package management software to install, update, and remove unneeded software.
That's a challenge for Mac users. One place where the Mac operating system, macOS, has always been behind Linux is in package management. There is no default package manager for Mac users, while Linux users have many options—from the familiar
apt to the modern choice of Flatpak. But what about us?
This is where Homebrew comes in. Homebrew fills the void as the de facto package manager for macOS (and as another option for Linux). It provides an incredibly smooth and straightforward experience for anyone familiar with the command line, and it's a good way to learn the command line if you're new to it.
If you're on a Mac and don't already have Homebrew, you can install it with:
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"
This command executes the installer script provided by the Homebrew team. If you prefer to be more cautious, you can
curl the file, then run it manually after reviewing it:
$ curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh --output homebrew_installer.sh $ more homebrew_installer.sh # review the script until you feel comfortable $ bash homebrew_installer.sh
Manage your command-line utilities with brew
Homebrew boasts that it "installs the stuff you need that Apple (or your Linux system) didn't" install by default. Installation happens with the
brew command, which gives us access to thousands of command-line utilities, but not more complex applications.
For us nerds, the utilities that fit into "the stuff you need" category include the handy
tree command that shows directory structures and
pyenv, which I use to manage multiple versions of Python.
You can see all the "formulae" that are available from Homebrew using the
search command, and I use the
wc command shows how many formulae there are:
# -l counts the number of lines $ brew search | wc -l 5013
There are over 5,000 formulae, which is an incredible amount of software. So it's best to have an idea of what you want before searching that huge list. Thankfully, it is easy enough to browse. Formulae are codified and centralized into the core repositories that are split by operating system (Mac in Homebrew Core and Linux in Linux Core). They are also available through the Homebrew API and listed on the website.
Word of mouth is another great method to find utilitites. With that in mind, here are some of my favorites if you're looking for inspiration:
nodenvto manage Python, Ruby, and Node.js versions (respectively)
imagemagickfor scriptable image edits
pandocfor scriptable document conversions (I often switch from .docx to .md or .html)
hubfor a better Git experience for GitHub users
tldrfor examples of how to use a command-line utility
As an example, take a look at tldr pages, a user-friendly alternative to scrolling through an application's man pages. You can confirm it's available by running
$ brew search tldr ==> Formulae tldr ✔
Success! The checkmark lets you know it is available. Now you can install it:
$ brew install tldr ==> Downloading https://homebrew.bintray.com/bottles/tldr-1.3.0_2.catalina.bottle.tar.gz Already downloaded: /Users/mbbroberg/Library/Caches/Homebrew/downloads/901bc14594a9283e9ab20aec942dc5a9a2befb7e96e1b0fcccb4e3257918813c--tldr-1.3.0_2.catalina.bottle.tar.gz ==> Installing tldr ==> Pouring tldr-1.3.0_2.catalina.bottle.tar.gz ? /usr/local/Cellar/tldr/1.3.0_2: 6 files, 35.5KB
Homebrew, thankfully, prebuilds the binaries, so you don't have to build from source code on your local machine. That saves a lot of time and CPU fan noise. Another thing I appreciate about Homebrew is that you can appreciate this feature without understanding exactly what it means.
But if you're into it, it can be fun to look at the complexity. Run
tldr, and you can see all the dependency management, the source code, and even public analytics:
$ brew info tldr tldr: stable 1.3.0 (bottled), HEAD Simplified and community-driven man pages https://tldr.sh/ Conflicts with: tealdeer (because both install `tldr` binaries) /usr/local/Cellar/tldr/1.3.0_2 (6 files, 35.5KB) * Poured from bottle on 2020-05-20 at 15:12:12 From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/tldr.rb ==> Dependencies Build: pkg-config ✔ Required: libzip ✔ ==> Options --HEAD Install HEAD version ==> Analytics install: 2,811 (30 days), 7,875 (90 days), 27,105 (365 days) install-on-request: 2,806 (30 days), 7,860 (90 days), 27,080 (365 days) build-error: 0 (30 days)
Finally, as in any good package manager, Homebrew's
brew uninstall is available to quickly clean and remove unused utilities.
Manage your applications with brew casks
Command-line utilities are a blast, but what about full-blown applications? Homebrew keeps its standard commands simple and installs only single-file applications through its default
brew command-line interface. Applications don't fit that structure. They have a more complex directory hierarchy that is much more than a single binary.
Fortunately, Homebrew on Mac includes a subcommand called "casks" for more complex multi-directory structures. What's especially nice is that
cask uses a similar command structure to the standard
brew commands, so you can use similar
brew search --cask | wc -l 4772
Wow, there are nearly 5,000 more applications to browse, which are easier to peruse on Homebrew's website.
I'll walk you through
cask with one of my new favorite applications: Meld (which I read about on Opensource.com). It's a feature-rich editor that helps manage merge conflicts. There is a download on its website, and I could run through the installer and drag-and-drop it into my Applications folder, but I don't do that anymore. I use Homebrew.
First, I confirm it's available through a slightly different syntax:
$ brew search --casks meld ==> Casks meld
Then I use the
cask sub-command to install it:
$ brew cask install meld ==> Downloading https://github.com/yousseb/meld/releases/download/osx-19/meldmerge.dmg ==> Downloading from https://github-production-release-asset-2e65be.s3.amazonaws.com/28624006/66cb25 ######################################################################## 100.0% ==> Verifying SHA-256 checksum for Cask 'meld'. ==> Installing Cask meld ==> Moving App 'Meld.app' to '/Applications/Meld.app'. ==> Linking Binary 'meld.wrapper.sh' to '/usr/local/bin/meld'. ? meld was successfully installed!
Homebrew not only installs the application but also makes it available in my current path under
/usr/local/bin/. Now I can run
meld from the command line or launch the application from the Applications folder.
Update everything with brew upgrade
The main reason I consistently use a package manager is so that I can consistently upgrade my software to avoid known security bugs and ensure I always have the latest features. If I install everything by hand, I have to keep an eye on each tool and application to know whether it has an auto-updater and, if not, pull down the latest releases myself.
Upgrades are where great package management shines. Since I don't have any special version requirements, I run only one command to update everything smoothly:
$ brew upgrade ==> Upgrading 6 outdated packages: helm 3.2.1 -> 3.2.2 firstname.lastname@example.org 3.8.2_4 -> 3.8.3 ipython 7.14.0 -> 7.15.0 go 1.14.2_1 -> 1.14.3 libzip 1.6.1 -> 1.6.1_1 sqlite 3.31.1 -> 3.32.1
If you have more complex needs or want to keep an eye on upgrades before installing them, there are plenty of feature flags available. For instance,
-n offers a "dry run" that lists available upgrades without installing them. You can also "pin" an application version to prevent upgrades.
Back up your installation
The command-line utility and application management jumps to a whole new level when tools allow you to back up your installation like any other dotfile in version control. Homebrew has that kind of functionality available to use under the
dump subcommand. It generates a
Brewfile, which is a reusable list of all the currently installed tools. To generate one from your installation, go into your preferred folder and run:
$ cd ~/Development/dotfiles # This is my dotfile folder $ brew bundle dump
When I change machines and want to install the same applications with Homebrew, I go to the folder with the Brewfile and run:
$ brew bundle
It will install all the listed formulae and casks on my new machine.
Go to Homebrew for package management
Homebrew is my go-to manager for command-line utilities and applications. It keeps me organized and up-to-date, and its design is a beautiful balance between ease of use and depth of functionality. Homebrew minimizes package management details to only what you need to know, and most users will benefit from that.
If you're already comfortable with Linux package managers, you may think Homebrew is too simple, but don't mistake Homebrew's ease of use for lack of features. Looking a little deeper reveals many advanced options that go far beyond what I showed you here. Adding
-h to any
brew subcommand shows the rich features available to upgrade, remove, troubleshoot, and even contribute new formulas using templates.
Overall, Homebrew makes being a command-line wielding Mac user a joy. In addition, it's open source, so you can contribute back to the code if you're so inclined. Give it a try, and let me know what you think by leaving a comment below.