Managing Homebrew with Brewfile
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:
brewpackages (CLI tools)caskpackages (GUI applications)taprepositories- 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:
bashbrew 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:
bashchezmoi 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:
bashbrew bundle check --file=~/Brewfile
Cleanup Unused Packages
Remove packages not in your Brewfile:
bashbrew 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:
bashmkdir -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:
- Homebrew Bundle Documentation
- Dev Environment Stack - Understanding configuration layers