Back up (Migrate) Homebrew Packages

Last updated on October 9, 2016

As one of the most popular package manager on OS X, Homebrew is indeed a very nice tool to manage packages. However, when you want to back up your packages, or migrate the packages onto another machine, Homebrew didn’t invent such a tool. If you are moving to an OS X of the same version, you can simply copy the Homebrew directory (default is /usr/local) to your new machine. Otherwise, we need to find a way to install the exactly same packages on your new machine. In order to accomplish the goal, I wrote a small piece of bash script to generate a restore script to install the packages.

The Backup (Migration) Script

The script itself is quite short:


echo '#!/bin/bash'
echo ''
echo 'failed_items=""'
echo 'function install_package() {'
echo 'echo EXECUTING: brew install $1 $2'
echo 'brew install $1 $2'
echo '[ $? -ne 0 ] && $failed_items="$failed_items $1" # package failed to install.'
echo '}'

brew tap | while read tap; do echo "brew tap $tap"; done

brew list | while read item;
echo "install_package $item '$(brew info $item | /usr/bin/grep 'Built from source with:' | /usr/bin/sed 's/^[ \t]*Built from source with:/ /g; s/\,/ /g')'"

echo '[ ! -z $failed_items ] && echo The following items were failed to install: && echo $failed_items'

For those impatient readers, you could simply download the script, and execute

bash > && chmod +x

Then you should have something similar to the following in your


function install_package() {
echo EXECUTING: brew install $1 $2
brew install $1 $2
[ $? -ne 0 ] && $failed_items="$failed_items $1"  # package failed to install.
brew tap homebrew/dupes
brew tap homebrew/games
brew tap homebrew/science
brew tap homebrew/versions
brew tap josegonzalez/php
install_package ant ''
install_package apple-gcc42 ''
install_package armadillo ''
install_package atk ''
install_package autoconf ''
install_package autoconf213 ''
install_package autojump ''
install_package automake ''
install_package bash ''

Copy to your new machine, install Homebrew and then execute this script.

What does the script do?

The script first defines install_package in the restore script, which is used to install packages and maintain the list of packages which are failed to install. Then, it uses brew taps to list all the taps you have and generate the corresponding script to tap those taps. Next, it uses brew list to obtain all the packages you have and uses brew info to get the options you used to install a package. For each package, it generates one line which uses install_package function to install the package with the options. Finally, it generates the line which lists the packages that are failed to install.

4 thoughts on “Back up (Migrate) Homebrew Packages

  1. bugstomper

    This article is a bit old, but was one of the top search hits when i went looking for homebrew backup of installed packages with options. The Brewfile feature mentioned in an earlier comment has been replaced with a newer version that is now automatically installed when run. “brew bundle dump” will create a Brewfile with all currently installed packages. See for details. That seems like it would replace everything that this script does.

    1. Hong Xu

      Well, I think your link gives a different feature. In your link, packages have to be listed first before the installation; but in my post, the package list is “extracted” from the currently installed packages. But the script in my post can be improved to generate a “Brewfile”.

    2. Dave

      I did a spit-take earlier this morning on “Real programmers use cat.” So I had to love the script written with echo.

      I keep a directory whose subdirectory names are leaf packages I want installed, followed by any needed options. I regularly make a clean reinstall of homebrew, followed by a scripted traversal of this directory. These directories make good places to store related information and notes. I disable folders by moving to an inactive directory.


Leave a Reply

Your email address will not be published. Required fields are marked *