# 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 - [[1. chezmoi]] - Managing dotfiles with chezmoi - [[Computer Tech/Unix/tmux/2. tmux Configuration with chezmoi]] - Syncing tmux config - [[Computer Tech/Unix/tmux/3. TPM - Tmux Plugin Manager]] - Using TPM installed via Homebrew **Related:** - [Homebrew Bundle Documentation](https://github.com/Homebrew/homebrew-bundle) - [[Dev Environment Stack]] - Understanding configuration layers