Automate your macOS development machine setup

My laptop was running a bit slow and there was an OS upgrade that I’ve been postponing for quite some time. So, on one rainy Friday afternoon, I decided to get my hands dirty and do a clean install of macOS Sierra. And why not automate it so I don’t have to think about it next time?

One of the benefits is that my team mates can use chunks of the configuration that are relevant to our work and use it for themselves.

Let’s have a look at the tools that we will use.


It’s a bunch of configuration files and directories that are in your home directory. For example vim uses .vimrc or a git uses .gitconfig. You want to bring them with you from your old machine.

Some people store them as a git repository but I just chuck them on Dropbox. Make sure that you are not revealing any sensitive files like your private SSH keys or infrastructure setup.

When you setup your new machine you create symlinks to the ones that you like to use. It can get pretty fancy or you can keep it simple with ln -s.


Homebrew is a package manager for macOS. And you can create your own bundles to set up whole environment.

Apart from that there is an extension for installing desktop applications — cask. You can search for the recipes with the following commands.

brew search vim
brew cask search google-chrome

When you find the mix of applications you bundle them together into a Brewfile.

cask_args appdir: '/Applications'

tap 'homebrew/bundle'
tap 'caskroom/cask'
tap 'homebrew/services'

brew 'vim'
brew 'tmux'
brew 'git'
brew 'ruby-build'
brew 'rbenv'

cask 'google-chrome'
cask 'vlc'
cask 'dropbox'

I like to keep my Brewfile in my Dropbox folder with the rest of the dotfiles. Now with the file you can run brew bundle and it installs everything for you. Easy.

Everything together

We have our configuration with dotfiles and we can install all the necessary applications with brew and cask. How about putting everything into one script that we can run and leave the computer do its thing?

I created an file that I keep with the rest of the files.


xcode-select --install

# dotfiles
ln -s ~/Dropbox/dotfiles/.bash_profile ~/.bash_profile
ln -s ~/Dropbox/dotfiles/.gitconfig ~/.gitconfig
ln -s ~/Dropbox/dotfiles/.tmux.conf ~/.tmux.conf
ln -s ~/Dropbox/dotfiles/.vimrc ~/.vimrc

# brew stuff
/usr/bin/ruby -e "$(curl -fsSL"
cd ~/Dropbox/dotfiles
brew bundle
cd ~

git clone ~/.vim/bundle/Vundle.vim
git clone ~/.tmux/plugins/tpm

# ruby
rbenv install 2.2.5
rbenv global 2.2.5

gem install bundler

echo "******************** Done ********************"
echo "Don't forget to configure SSH properly with key and config"

Firstly, it installs XCode command line tools — if you need to install the full version you might need to do that through AppStore. I haven’t found any way around that yet.

After installing XCode the script takes care of the dotfiles and links them into your home directory. And when those are sorted it starts the brew magic.

There is a few custom commands afterward — installing plugin managers for tmux and vim and installing ruby with rbenv. You can also use terminal to customize macOS behaviour or do other things that you would normally do by hand.


And with that a fresh OS install is not a pain anymore. After finishing the installation and encrypting your disk you copy your backed up Dropbox folder into your home directory, run

. ~/Dropbox/dotfiles/

and you can go for a surf, come back and have your computer ready. Unless you need to compile Qt with Webkit. Then you might go for two surf sessions at least.


Victor Maslov aka Nakilon: My relevant gist

Gabriel Filipe Gizotti: fresh helped me a lot

ege: Brewfile also let you add apps from Mac App Store thanks to But doesn’t work with 2FA-enabled account yet. I hope devs find a solution.

brew 'mas' / brew install mas
mas '1Password'

Phil Pirozhkov: I find it really hard maintaining the up to date list of formulae by hand and came up with the following:

Show installed formulae that are not dependencies of another installed formula:

brew leaves >! .formulae
brew cask list >! .casks


brew install $(< .formulae )
brew tap caskroom/cask
brew cask
brew cask install $(< .casks)

Would you like to get the most interesting content about programming every Monday?
Sign up to Programming Digest and stay up to date!