Homebrew BrewUI runs every brew command in a clean shell

21 hours ago

Homebrew now has an official Mac app, called BrewUI. It runs every brew command with none of your personal Terminal setup, and it does that on purpose.

Ask

Ask about this presentation

Answers are generated from this presentation.

Chapters

  1. 0:00Homebrew BrewUI · runs brew without your Terminal setup
  2. 0:08BrewUI puts Homebrew’s commands behind buttons
  3. 0:43Homebrew’s own app has to ignore your Terminal setup
  4. 0:54Every button shows the exact brew command it will run
  5. 1:18Four launch week bug reports, all fixed by one change
  6. 1:52Until 15 September, BrewUI loaded your shell settings on purpose
  7. 2:36Now brew runs in a blank zsh that searches three folders
  8. 3:16One system file always runs, so BrewUI cleans up after it
  9. 3:40Your Homebrew settings now go in brew.env files
  10. 4:15Your Mac now has two Homebrew environments, and they can disagree
  11. 4:55Installs, upgrades and removals wait in one queue
  12. 5:13Five tabs, and the ones that run brew show the command
  13. 5:34The README says stable, and the app shipped five releases in seven days
  14. 5:59Homebrew already had Mac apps, and BrewUI is the one its maintainers build
  15. 6:20BrewUI needs macOS 26 and Homebrew in its default folder
  16. 6:50brew.env works for every program that runs brew without you
  17. 7:06Install BrewUI if you teach Homebrew, wait if your setup is custom
  18. 7:26Install BrewUI with one brew command
  19. 7:46Where do your Homebrew settings live today?
Show transcript

Homebrew BrewUI · runs brew without your Terminal setup

BrewUI’s Installed tab with 1Password selected

Homebrew

BrewUI
Homebrew’s official Mac app runs brew without your Terminal setup
SwiftAGPLmacOS 26 and later

Homebrew now has an official Mac app, called BrewUI. It runs every brew command with none of your personal Terminal setup, and it does that on purpose.

BrewUI puts Homebrew’s commands behind buttons

BrewUI’s Installed tab, a Terminal command box bottom right
Homebrew 7 · fully released, 13 September
brew.sh, Homebrew 7 release post
the Installed tab showing brew’s help text and an unknown command error
one user’s Installed tab, 14 September · BrewUI issue #193

Homebrew is the free tool Mac developers use to install command line programs, by typing brew install and a name. BrewUI puts Homebrew in a window, with buttons to browse, install, upgrade and remove, and every button shows the brew command behind it. Homebrew 7 came out on September 13th and called the app fully released. The next day, one user opened the Installed tab and got Homebrew’s help text, ending in an unknown command error. The unknown word came from that user’s shell settings. Your shell is the program in the Terminal window that reads what you type, and it runs a settings file every time it starts.

Homebrew’s own app has to ignore your Terminal setup

what it runs instead, and why I’d wait a few releases
why it ignores your setupthe blank shellthe catch

By the end you’ll know why Homebrew’s own app ignores the Terminal setup you spent years tuning, what it runs instead, and why I’d still wait a few releases before trusting the word stable. The reason starts with how launch week went.

Every button shows the exact brew command it will run

built for people who would rather not use Terminal
1Password’s detail pane with its Terminal command box
rule 1always show the exact command
rule 2brew stays in charge, the app never touches Homebrew’s internals
BrewUI README and design notes

The README says who BrewUI is for: people who would rather not use Terminal. The design notes set two rules. The first is to always show the exact command. The second is to let brew stay in charge, so the app only runs the same commands you would type and never reaches into Homebrew’s own files. Pick 1Password, and the uninstall command for it sits right beside the Uninstall button. I like that it teaches you the command while it runs it.

Four launch week bug reports, all fixed by one change

issue 193
Unknown command: brew PROMPT_SUBST
Installed, Upgrades, Configuration, Doctor
issue 198
Unknown command: brew opt
issue 195
Kiro CLI had an Error!: stdin and stdout must both be tty handles
issue 191
“all others just leave a blank tab indefinitely”
fixed by the same change
Discover still worked · it reads the package list from the web
BrewUI issues #191, #193, #195, #198

Launch week brought four bug reports, and one change fixed all four. The user with the stray word saw the same error on four tabs: Installed, Upgrades, Configuration, and Doctor, which is Homebrew’s health check for your setup. Another user got unknown command, brew opt. A third user had Kiro CLI, a coding assistant that runs in Terminal, and Update All failed with an error from Kiro that wanted a real terminal. A fourth user pressed buttons that opened tabs and stayed blank. For the user who got brew opt, one tab still worked. Discover reads Homebrew’s package list from the web instead of running brew.

Until 15 September, BrewUI loaded your shell settings on purpose

BrewUI
your shell
.zshrc
brew
arguments: ["-l", "-i", "-c", shellCommand]
“the cost of exact-Terminal parity”
prompt theme
shortcuts
tool hooks
extra folders
a word from the settings file
brewUnknown command
in Terminal, the file finishes before you type

Until September 15th, BrewUI loaded your Terminal setup on purpose, and I did not expect that. The app started your shell the way Terminal does, which runs your zshrc, the settings file your shell reads each time it opens. A comment in the code calls the risk the cost of matching Terminal exactly. Your zshrc is written for you at a keyboard. It holds your prompt theme, your shortcuts, extra folders to search, and hooks, meaning bits of code other tools add to run at startup. The app handed brew’s command to that shell, and code in the settings file can overwrite the command. So a word from someone’s settings replaced the real command, and brew said unknown command. Another user got the name of a setting from fish, a different shell. In Terminal, your zshrc finishes running before you type anything, so it never touches your command.

Now brew runs in a blank zsh that searches three folders

your Terminal
BrewUI
settings files
used
used
exported settings
used
used
shortcuts
used
used
custom folder list
used
used
usedignored
usedignored
usedignored
usedignored
/bin/zsh --no-rcs --no-global-rcs
PATH = <brew folder>:/usr/bin:/bin
brew’s folder/usr/bin/bin
self-upgrade runs the same way
BrewUI pull request #194, merged and released 15 September

The fix is one pull request, a proposed code change, and Homebrew maintainer Mike McQuaid merged it on September 15th. The release went out the same day, and it reverses the rule. BrewUI now runs brew through zsh, the shell every Mac ships with, with both switches that load startup files turned off. It starts from an empty environment, meaning none of the settings programs usually inherit. The list of folders it searches for programs has exactly three entries: the folder brew lives in, then two system folders. Brew’s command now travels as plain text that no settings file can rewrite. Your shortcuts, exported settings and custom folder list are all ignored, and the app’s own self-upgrade runs the same way.

One system file always runs, so BrewUI cleans up after it

system file
BrewUI
blank zsh
brew
environment emptied a second time
console
startup output thrown away
marker line, new each run
BrewUI README

One system file still runs every time zsh starts, and zsh has no switch to turn it off. So BrewUI lets that file run, then empties the environment a second time, right before brew starts. The app also prints a marker line that is unique to each run, and throws away everything printed above it, so a welcome banner can’t end up inside a Doctor report. This is my favourite part. The maintainers wrote down the one gap they can’t close, and they patched around it.

Your Homebrew settings now go in brew.env files

~/.homebrew/brew.env
HOMEBREW_NO_ENV_HINTS=1
NAME=value · no export · no expansion
yours~/.homebrew/brew.env
this Homebrew install<prefix>/etc/homebrew/brew.env
the whole Mac/etc/homebrew/brew.env
unless the Mac-wide file claims priority
Homebrew documentation

Your Homebrew settings now go in brew.env, a plain text file that Homebrew reads itself, with no shell involved. Each line is a name, an equals sign and a value. Homebrew doesn’t allow the export keyword here, or anything that expands, like a dollar sign. There are three of these files. Yours sits in your home folder, one belongs to the Homebrew install, and one covers the whole Mac. Yours beats the install’s file, and the install’s file beats the Mac’s. The exception is a Mac-wide file that claims priority. That lets whoever manages the Mac pin a setting you can’t override.

Your Mac now has two Homebrew environments, and they can disagree

Terminal
brew’s folder
Homebrew’s sbin
folders your .zshrc adds
inside BrewUI
brew’s folder
/usr/bin
/bin
Configuration tab and Doctor describe this side
“Include Homebrew sbin in the shell PATH”
open change, Mike McQuaid, 16 September · avoids false Doctor warnings
“That is intentional behaviour.”
Mike McQuaid, to a Workbrew user, 15 September
the Workbrew user’s Configuration tab error
reported on the build before the fix
BrewUI #218 and #203

That leaves your Mac with two Homebrew environments, and they can disagree. BrewUI’s Configuration tab and Doctor describe brew inside the app. Terminal can tell you something different. The next morning, Mike McQuaid opened a change to add a fourth folder to the list, Homebrew’s sbin, a folder where some packages put their programs. Doctor in the app was raising warnings that Terminal doesn’t. And a Workbrew user hit the same gap. Workbrew is a tool companies use to manage Homebrew on work Macs, and this user’s zshrc pointed brew at it. Mike McQuaid’s answer was one line: that is intentional behaviour. If something works in Terminal and fails in the app, the gap between those two environments is the first place I’d look.

Installs, upgrades and removals wait in one queue

screens
command centre
brew
package list on the web
running
waiting
failed
package list on the web
browsing skips the queue
BrewUI design notes

Under the buttons, BrewUI keeps a single command centre. Installs, upgrades and removals run through the command centre one at a time. It tracks what’s running and what failed. Browsing changes nothing on your Mac, so it reads Homebrew’s package list from the web and stays out of the queue. I’d want exactly that in any app that changes what’s installed on my machine.

Five tabs, and the ones that run brew show the command

the Terminal command box: brew uninstall --cask 1password
Installed · 1Password selected
the Doctor tab: your system is ready to brew
the Doctor tab

The sidebar has five tabs: Discover, Installed, Upgrades, Doctor and Configuration. On Installed, pick a package and a Terminal command box shows the brew command next to the Uninstall button. On Doctor, the console is labelled brew doctor, and a healthy Mac gets the line: your system is ready to brew. I’d hand this to someone learning Homebrew for that reason alone.

The README says stable, and the app shipped five releases in seven days

release
9
10
11
12
13
14
15
16
September
bug report
four of five tabs failing for one user
fix merged · design in place since June, reversed
version number still starts with a zero
BrewUI README and releases

The README calls BrewUI stable, and Homebrew 7 calls it fully released. The five releases landed between September 9th and 15th. On September 14th, one user’s screenshots showed four of the five tabs failing. The fix reversed a design the app had used since June. And the version number still starts with a zero. I read stable here as a promise about the design. I’d still expect the app to keep changing week to week.

Homebrew already had Mac apps, and BrewUI is the one its maintainers build

app
what it is
Cakebrew
last release 2021
Tappie
free Mac app
Brew Browser
open source, installs from its own source
BrewUI
built by Homebrew’s maintainers · in Homebrew’s main catalogue of Mac apps
each project’s GitHub page

Mac apps for Homebrew already exist. Cakebrew had its last release in 2021. Tappie is a free Mac app, and Brew Browser is an open source app that installs from its own Homebrew source. BrewUI is the one Homebrew’s own maintainers build, and it sits in Homebrew’s main catalogue of Mac apps under the Homebrew name. For a tool that changes what’s installed on your Mac, I care about who builds it.

BrewUI needs macOS 26 and Homebrew in its default folder

macOS 26 Tahoe or later
default Homebrew folder only
“This is intentionally unsupported for now, sorry.” Mike McQuaid, #199
Homebrew’s own packages only, per the design notes
settings in your .zshrc are ignored
AGPL licence

The catch comes in five parts. You need macOS 26, called Tahoe, or newer. Homebrew has to sit in its default folder. When a user asked for a custom location, Mike McQuaid replied: this is intentionally unsupported for now, sorry. The design notes limit the app to Homebrew’s own packages, without extra sources. If your Homebrew settings live in your zshrc, the app ignores them until you move them. And the licence is the AGPL, an open source licence that also covers anyone who runs a changed copy as an online service.

brew.env works for every program that runs brew without you

Terminal
BrewUI
scheduled job
yours~/.homebrew/brew.env
this Homebrew install<prefix>/etc/homebrew/brew.env
the whole Mac/etc/homebrew/brew.env
move your settings once

The same move helps outside BrewUI. Scheduled jobs, editor tasks and other apps run your tools without you at the keyboard, and they often start without your zshrc too. Homebrew reads brew.env itself, so the file reaches all of them. I’d move my Homebrew settings there this week, even if I never open the app.

Install BrewUI if you teach Homebrew, wait if your setup is custom

install nowon macOS 26, learning the commands, or setting up Macs for people who avoid Terminal
waitcustom Homebrew folder or extra package sources
skipyou already live in Terminal; take brew.env

Should you install it? Install it now if you’re on macOS 26 and want to learn the commands by watching them, or if you set up Macs for people who avoid Terminal. Wait a few releases if your Homebrew lives in a custom folder, or you use extra package sources. Skip it if you already live in Terminal. I’d still move my settings into brew.env, because that part helps everyone.

Install BrewUI with one brew command

brew install --cask homebrew-app
macOS 26 and later · Swift · AGPLgithub.com/Homebrew/BrewUI
the .pkg download also installs Homebrew if your Mac lacks it

It’s Homebrew slash BrewUI, on GitHub. Install it with brew install, dash dash cask, homebrew dash app. Cask is Homebrew’s word for a Mac app. The package installer on the releases page also installs Homebrew itself, but only if your Mac doesn’t have it yet. BrewUI needs macOS 26, it’s written in Swift, Apple’s own programming language, and it’s AGPL.

Where do your Homebrew settings live today?

your .zshrc or brew.env
new repo tomorrow

That broken Installed tab came from one word in one person’s settings file. So where do your Homebrew settings live today, in your zshrc or already in brew.env? Tell me in the comments. New repo tomorrow.