Managing macOS with Brew Bundle Brewfile

Easily manage your macOS environment with brew Bundles and a Brewfile to create bundles to spin up a consistent environment everytime!

Package Management

Package management gives you an easy way to spin up a fresh install of an OS with a known environment of applications ready to go. We’ve got very apt or apk or yum package managers for Linux, scoop or choco for Windows and brew for macOS.

Life before Bundles

In the past I’ve used a technique to break up the installation and have a bash script run through the installation for me. You can see this in my dotprofiles / macos / install-brew.sh file.

Basically:

BASE=(
    # System
    bash-completion
    curl
    git
    htop
    ...
)
TAPS=(
    homebrew/cask
    homebrew/cask-fonts
    tinygo-org/tools
)
CASKS=(
    # System
    keepassxc
    ...
)
FONTS=(
    font-inconsolata
)

Then with the powers combined, run through the installation with some tricks:

show_info "Installing BASE brew packages..."
brew install ${BASE[@]}
show_success "Installing BASE brew packages...Done!"

This worked relatively well, but it would install the entire arrays worth of packages - and if you’re like me, you’ll have more than one Mac to install, so that means commenting out specific bits (or creating another script that seperates them all - which I was too lazy to do it appears!).

Brew Bundles

Brew comes with an extra bit of goodness which are called Bundles that lets you do the above but in a much nicer, cleaner way. What’s incredibly awesome about Bundles is that we can opt to not only have CLI & Cask applications & fonts, but also Mac Store Apps (mas).

They’re stored in a ~/Brewfile (by default) and look like this:

tap "homebrew/cask"
tap "homebrew/cask-fonts"
...
brew "awscli"
brew "diff-so-fancy"
brew "fd"
brew "git"
brew "gnupg"
brew "go"
brew "htop"
...
mas "Amphetamine", id: 937984704
...

You setup your taps at the top, then all the applications (in any tap) and finally the mas entries at the bottom are the Mac App Store applications - like Amphetamine!

Working with Bundles

If you’ve not used brew before, you can install brew and setup your base environment as you wish.

Freeze your Bundle

Much like pip freeze you can create a bundle of your current brew environment by the dump command:


brew bundle dump

This will create a Brewfile in which ever directory you’re in akin to the example above. You can opt to name & place this file elsewher with the --file switch:


brew bundle dump --file=~/my-bundles/Brewfile-base

If the file already exists, you’ll not be able to overwrite it without the --force switch:


brew bundle dump  --force --file=~/my-bundles/Brewfile-base

Applying your Bundle

Now that you’ve created your Brewfile, how does one import it on a fresh install?


brew bundle install --file=~/my-bundles/Brewfile-base

Or if you have a default ~/Brewfile just:


brew bundle install

Depending on what’s in there, it may take quite sometime (like XCode!), so be patient, it’s brewing!

Clean house to match Brewfile

If you want to ensure that you have a clean environment to match your Brewfile you can ask brew to cleanup your existing packages and ensure only the ones defined are installed with:


brew bundle install --file=~/my-bundles/Brewfile-base

Managing Brewfiles

Here are some extra tips for managing your Brewfile and making life easier.

Best Taps to tap

There are some really nice taps you can place at the top of your Brewfile to make life easier.

  • tap "homebrew/cask" - For casks or GUI Applications
  • tap "homebrew/cask-fonts" - For fonts, really useful for installing consistent fonts across installs.
  • tap "homebrew/services" - For background services using launchctl on macOS
  • tap "buo/cask-upgrade" - Upgrade all cask apps via Cask-Upgrade Tool.
  • brew mas - This installs the Mac App Store app installation via mas-cli

Multiple Brewfiles

You can opt for one large Brewfile or as I like to do, layer things based on environment (or machine).

Often, I have a base or min which contains the bare essentials across all environments/machines - which contains things like git, htop, fd, tmux, zsh etc. Then specific brewfiles for circumstances - eg. Brewfile-dev or Brewfile-fleetwoodmac which is specific to FleetwoodMac (the actual Macbook).

Find a pattern that works for you and break up your main Brewfile.

Upgrading easily with cask-upgrade

You can easily upgrade all your Brew Casks with the inclusion of the last tap in that list (tap "buo/cask-upgrade") with:


brew cu

Related Articles