Recently, I had the fun task of setting up my Mac from scratch… twice.

The first time, because my computer died after a macOS update and the second time because I got a new computer from work. In both cases, I decided not to use a Time Machine Backup, so that means I had to install a lot of apps to make my computer feel familiar. This endeavour takes a lot of time, mostly spent looking for installers and waiting for downloads/installs and, sometimes waiting for expanding compressed files (I’m looking at you Xcode). For me, things don’t end here, sometimes I don’t remember ALL the apps I need to install and it’s a bit annoying to realise what’s missing when you are mid-work and something’s not there.

To improve this, I decided to make good use of Homebrew’s Bundle to automate this process.

Bundle

When we write software, we sometimes manage our dependencies using package managers (e.g. SPM, Cocoapods) but when it comes to software in our OS we do this manually and need to install stuff from various places.

Here, Bundle comes to the rescue.

We’ll start by installing Homebrew, entering this command in a Terminal window:

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

Next, we’ll create a Brewfile file by dumping all software currently installed in our computer

brew bundle dump

If we open the file created by dump, we’ll find a list of apps installed on our computer, but for now, this is limited to apps installed with Homebrew and from the Mac App Store.

In this file, we usually find the following commands:

  • tap a Git repository of Formulae and/or commands
  • brew regular Homebrew command-line apps
  • mas Mac App Store apps
  • cask apps distributed as binaries

Now it’s time to clean up this file a bit, add some comments to divide it into sections, and add missing apps that were not found by dump.

Here’s the “cleaned up” version I use:

cask_args appdir: "/Applications"

tap "homebrew/bundle"
tap "homebrew/cask"
tap "homebrew/core"

brew "mas"

# General
mas "1Password", id: 1333542190
mas "Numbers", id: 409203825
mas "Pages", id: 409201541
mas "Keynote", id: 409183694

mas "Ulysses", id: 1225570693
mas "Pixelmator Pro", id: 1289583905
mas "Magnet", id: 441258766
mas "The Unarchiver", id: 425424353
mas "GarageBand", id: 682658836
mas "Mactracker", id: 430255202
mas "Whatsapp", id: 1147396723

cask "alfred"
cask "expressvpn"
cask "grandperspective"
cask "vlc"
cask "istat-menus"
cask "skype"
cask "google-chrome"

# Dev
mas "Xcode", id: 497799835
mas "Developer", id: 640199958
mas "Slack", id: 803453959
mas "Spark", id: 1176895641

brew "carthage"
brew "fastlane", link: false
brew "git-lfs"
brew "sourcery"
brew "swiftlint"
brew "node"

cask "iterm2"
cask "visual-studio-code"
cask "tower"
cask "dash"
cask "postman"
cask "sequel-pro"

# - Optional
# cask "obs"

# - Gadgets
# tap "homebrew/cask-drivers"
# cask "elgato-stream-deck"
# cask "logitech-options"
# cask "logitech-g-hub"
# cask "philips-hue-sync"

# - Raspberry Pi
# cask "raspberry-pi-imager"

# Pico
# brew "cmake"
# tap "ArmMbed/homebrew-formulae"
# brew "arm-none-eabi-gcc"

As we can see from this example, the Brewfile is divided into three sections:

  • General: All apps for day-to-day use
  • Dev: Apps related to software development
  • Optional: Other apps that rely on external hardware (e.g. Stream Deck, Hue Lights)

Once this file is ready, we just need to run:

brew bundle

And voilà!

Homebrew will install everything we defined on the Brewfile file. Now we can use the time it takes to install all of this in something more productive/fun.

Summary

In this article we saw how to use Bundle as some sort of dependency manager for apps on macOS.