How do you migrate a Homebrew installation to a new location?

I have a Homebrew installation in $HOME/brew, and historically it has worked well. Unfortunately, over time Homebrew has become less and less tolerant of installations outside of /usr/local. Various formulae make hard assumptions about the installation prefix, and do not work properly (i.e., were not tested) with a non-standard prefix. The brew doctor command even goes so far as to warn about this now:

Warning: Your Homebrew is not installed to /usr/local
You can install Homebrew anywhere you want, but some brews may only build
correctly if you install in /usr/local. Sorry!

As such, I would now like to migrate my Homebrew installation over to /usr/local. However, I am loath to simply mv all the files, as I suspect this will cause problems. I could not find any instructions on the Homebrew site or here on migrating an existing installation to a new prefix. Of course, I could uninstall Homebrew and then reinstall it, but I would prefer not to rebuild all my kegs.

Is there any existing script or documented practice for performing such a migration?

Or is this impossible due to hardcoded absolute paths in linked binaries?


The modern way to do this is with homebrew-bundle.

brew tap Homebrew/bundle
brew bundle dump # Creates 'Brewfile' in the current directory
# later ...
brew bundle # Installs packages listed in 'Brewfile'

I just wrote a script to achieve the goal to migrate homebrew packages to a new system, which also applies for your case (named


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'

You should first run this script on your original system to generate a restore script:

./ > && chmod +x

Then, after installing Homebrew on your new system (in your case the same system), simply run to install all those packages you have on your original system.

The benefits of this script over the one given by @ctrueden is that this script also tries to back up the installation options you used when you installed the packages.

A more detailed description is in my blog.

As suggested by Peter Eisentraut, I indeed ended up migrating my Homebrew installation by reinstalling it. You can script things a bit to retap all your extra taps, and reinstall all your previously installed kegs, without too much manual work:


# save list of kegs for later reinstallation
brew list > kegs.txt

# back up old Homebrew installation
mv $HOME/brew $HOME/old-brew

# install Homebrew into /usr/local
ruby -e "$(curl -fsSL"

# retap all the taps
# NB: It is not enough to move the tap repos to their new location,
# because Homebrew will not automatically recognize the new formulae.
# There might be a configuration file we could edit, but rather than
# risk an incomplete data structure, let's just retap everything.
for tapDir in $HOME/old-brew/Library/Taps/*
do (
  cd $tapDir
  tap=$(git remote -v | \
    grep '(fetch)' | \
    sed 's/.*\///' | \
    sed 's/ (fetch)//')
  /usr/local/bin/brew tap $tap
) done

# reinstall all the kegs
/usr/local/bin/brew install $(cat kegs.txt)

# much later... ;-)
rm -rf kegs.txt $HOME/old-brew

Of course, customized Homebrew installations will have additional wrinkles. For example, if you have committed changes to any of your Homebrew-related Git repos, you may want to import that work before reinstalling your kegs or blowing away your old installation:

cd /usr/local
for f in $(find . -name '.git')
do (
  repoDir=$(dirname $f)
  cd $f/..
  git remote add old-brew-$f $(dirname $HOME/old-brew/$f/..)
  git fetch old-brew-$f
) done

Note that I only tested the second snippet above very lightly, as I personally have not customized my Homebrew in such a way.

Another aspect of Homebrew not addressed by this approach is custom flags using during your original installation. For example, to install wine you need to install various dependencies with the --universal flag, and the script above will not reinstall them with such flags enabled. See @xuhdev's answer for a solution that does so.

Or is this impossible due to hardcoded absolute paths in linked binaries?

Indeed. You'll need to reinstall everything from scratch.

Need Your Help

<system_error> categories and standard/system error codes

c++ c++11 winapi posix system-error

C++11 introduced the &lt;system_error&gt; header containing a generic system to handle error codes. An std::error_code is a tuple containing an int, the error code, and a reference to an std::

Django: Best way to unit-test an abstract model

django unit-testing django-models abstract

I need to write some unit tests for an abstract base model, that provides some basic functionality that should be used by other apps. It it would be necessary to define a model that inherits from i...