← Back to articles

Managing Homebrew with Brewfile

Path: Computer Tech/System Configuration/Environment Setup/Dev Environment and Versioning/Managing Homebrew with Brewfile.mdUpdated: 2/3/2026

Managing Homebrew with Brewfile

A Brewfile is Homebrew's way of managing all your installed packages, casks, and even VS Code extensions in one declarative file. Combined with chezmoi, it makes your entire development environment portable and reproducible.

What Problem Does This Solve?

Without Brewfile:

  • Manually install packages one by one on new machines
  • Forget which packages you had installed
  • Different package versions across machines
  • No version control for your tooling setup

With Brewfile:

  • One command installs everything: brew bundle install
  • Full history of what tools you use
  • Identical environments across all machines
  • Easy to share with team members

Basic Workflow

Step 1: Generate Your Current State

Generate a Brewfile from your current Homebrew installation:

bash
# Create Brewfile in your home directory
brew bundle dump --file=~/Brewfile --force

This creates ~/Brewfile with all your currently installed:

  • brew packages (CLI tools)
  • cask packages (GUI applications)
  • tap repositories
  • VS Code extensions (if VS Code is installed)

Step 2: Review and Clean Up

Edit ~/Brewfile to remove things you don't want to track:

bash
# View your Brewfile
cat ~/Brewfile

# Edit it
nano ~/Brewfile  # or use your preferred editor

Common things to keep:

  • Essential CLI tools: git, tmux, tpm, curl, wget
  • Development tools: node, python, docker, gh
  • Your terminal: ghostty, alacritty, etc.
  • Editors: neovim, cursor, sublime-text

Common things to remove:

  • One-off experiments you don't use anymore
  • Applications you installed for specific projects
  • Duplicates or deprecated packages

Step 3: Install from Brewfile

On any machine, install everything in your Brewfile:

bash
brew bundle install --file=~/Brewfile

This is idempotent—running it multiple times is safe. It only installs missing packages.

Integration with chezmoi

Pattern 1: Manual Sync (Simplest)

Don't manage the Brewfile with chezmoi. Instead, regenerate it before syncing:

bash
# Before committing config changes
brew bundle dump --file=~/Brewfile --force
cd ~/.local/share/chezmoi
git add .
git commit -m "Update configs and regenerate Brewfile"
git push

# On new machine
brew bundle install --file=~/Brewfile
chezmoi init
chezmoi apply

Pros:

  • ✅ Always reflects current state
  • ✅ No merge conflicts
  • ✅ Simple mental model

Cons:

  • ⚠️ Brewfile isn't version-controlled
  • ⚠️ Must remember to regenerate before syncing

Pattern 2: chezmoi-Managed Brewfile (Recommended)

Add Brewfile to chezmoi for version control:

bash
# Add Brewfile to chezmoi
chezmoi add ~/Brewfile

# On new machine, install from Brewfile first
brew bundle install --file=~/Brewfile

# Then apply chezmoi configs
chezmoi init
chezmoi apply

Workflow on your main machine:

bash
# Install new tool
brew install newtool

# Regenerate Brewfile
brew bundle dump --file=~/Brewfile --force

# Add to chezmoi and commit
chezmoi add ~/Brewfile
cd ~/.local/share/chezmoi
git add .
git commit -m "Add newtool to Brewfile"
git push

Workflow on other machines:

bash
# Pull latest configs
chezmoi update

# Install new packages
brew bundle install --file=~/Brewfile

Pros:

  • ✅ Version-controlled package list
  • ✅ Git history of what tools you added/removed
  • ✅ Can see diffs between machines

Cons:

  • ⚠️ Must manually regenerate Brewfile
  • ⚠️ Potential for drift if you forget to regenerate

Pattern 3: Automated Sync (Advanced)

Use chezmoi scripts to automate the sync:

Create ~/.local/share/chezmoi/.chezmoiscripts/run_before_apply.sh:

bash
#!/bin/bash
# Auto-update Brewfile before applying configs

echo "Updating Brewfile from current Homebrew state..."
brew bundle dump --file=~/Brewfile --force

Add to chezmoi:

bash
chezmoi add ~/.local/share/chezmoi/.chezmoiscripts/run_before_apply.sh

Now every time you run chezmoi apply, it regenerates your Brewfile automatically!

Pros:

  • ✅ Never forget to regenerate
  • ✅ Always in sync

Cons:

  • ⚠️ May capture temporary installs you didn't want to track
  • ⚠️ Less explicit about what changed

Recommended Workflow for Your Setup

Based on your chezmoi + tmux + Ghostty setup, I recommend Pattern 2 (chezmoi-managed with manual regeneration):

Initial Setup

bash
# 1. Install tmux and tpm via Homebrew
brew install tmux tpm

# 2. Regenerate Brewfile
brew bundle dump --file=~/Brewfile --force

# 3. Add to chezmoi
chezmoi add ~/Brewfile

# 4. Commit
cd ~/.local/share/chezmoi
git add .
git commit -m "Add Brewfile with tmux and tpm"
git push

Daily Workflow

When installing new tools:

bash
# Install the tool
brew install sometool

# Immediately regenerate Brewfile
brew bundle dump --file=~/Brewfile --force

# Add to chezmoi
chezmoi add ~/Brewfile

# Commit
cd ~/.local/share/chezmoi
git add Brewfile
git commit -m "Add sometool to Brewfile"
git push

When syncing to another machine:

bash
# Pull latest configs
chezmoi update

# Install missing packages
brew bundle install --file=~/Brewfile

Brewfile Structure

Here's what a typical Brewfile looks like:

ruby
# Homebrew taps (third-party repositories)
tap "homebrew/cask"
tap "homebrew/cask-fonts"

# CLI tools
brew "git"           # Version control
brew "tmux"          # Terminal multiplexer
brew "tpm"           # Tmux plugin manager
brew "chezmoi"       # Dotfile manager
brew "ripgrep"       # Fast search tool
brew "fzf"           # Fuzzy finder
brew "gh"            # GitHub CLI

# GUI applications
cask "ghostty"       # Terminal emulator
cask "docker"        # Containerization
cask "cursor"        # Code editor

# VS Code extensions (if VS Code installed)
vscode "github.copilot"
vscode "esbenp.prettier-vscode"

Pro Tips

Keep It Organized

Add comments to your Brewfile to remember why you installed things:

ruby
# Terminal tools
brew "tmux"          # Session management
brew "tpm"           # Tmux plugins

# Audio production
brew "lilypond"      # Music notation
cask "reaper"        # DAW

Check What Would Be Installed

Before installing, see what's missing:

bash
brew bundle check --file=~/Brewfile

Cleanup Unused Packages

Remove packages not in your Brewfile:

bash
brew bundle cleanup --file=~/Brewfile --force

⚠️ Warning: This removes anything not listed in your Brewfile!

Install Only Specific Categories

bash
# Only install brews, skip casks
brew bundle install --file=~/Brewfile --no-cask

# Only install casks
brew bundle install --file=~/Brewfile --no-brew

Troubleshooting

Brewfile conflicts on chezmoi update

If chezmoi shows conflicts in Brewfile:

bash
# Accept incoming version (from Git)
chezmoi merge ~/Brewfile

# Or regenerate from current state
brew bundle dump --file=~/Brewfile --force
chezmoi add ~/Brewfile

Package fails to install

bash
# Update Homebrew first
brew update

# Try installing individually
brew install packagename

# Check for issues
brew doctor

TPM installed via Homebrew doesn't work

When installing TPM via Homebrew, update your .tmux.conf:

bash
# Change from:
run '~/.tmux/plugins/tpm/tpm'

# To:
run '/opt/homebrew/opt/tpm/share/tpm/tpm'

Or create a symlink:

bash
mkdir -p ~/.tmux/plugins
ln -s /opt/homebrew/opt/tpm/share/tpm ~/.tmux/plugins/tpm

Next Steps

  • chezmoi - Managing dotfiles with chezmoi
  • Computer Tech/Unix/tmux/tmux Configuration with chezmoi - Syncing tmux config
  • Computer Tech/Unix/tmux/TPM - Tmux Plugin Manager - Using TPM installed via Homebrew

Related: