Homebrew BrewUI runs every brew command in a clean shell

1 month 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 about 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
  1. 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.

    Slide text
    BrewUI’s Installed tab with 1Password selected

    Homebrew

    BrewUI
    Homebrew’s official Mac app runs brew without your Terminal setup
    Swift AGPL macOS 26 and later
  2. 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.

    Slide text
    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
  3. 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.

    Slide text
    what it runs instead, and why I’d wait a few releases
    why it ignores your setup the blank shell the catch
  4. 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.

    Slide text
    built for people who would rather not use Terminal
    1Password’s detail pane with its Terminal command box
    rule 1 always show the exact command
    rule 2 brew stays in charge, the app never touches Homebrew’s internals
    BrewUI README and design notes
  5. 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.

    Slide text
    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
  6. 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.

    Slide text
    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
  7. 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.

    Slide text
    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
  8. 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.

    Slide text
    system file
    BrewUI
    blank zsh
    brew
    environment emptied a second time
    console
    startup output thrown away
    marker line, new each run
    BrewUI README
  9. 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.

    Slide text
    ~/.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
  10. 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.

    Slide text
    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
  11. 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.

    Slide text
    screens
    command centre
    brew
    package list on the web
    running
    waiting
    failed
    package list on the web
    browsing skips the queue
    BrewUI design notes
  12. 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.

    Slide text
    the Terminal command box: brew uninstall --cask 1password
    Installed · 1Password selected
    the Doctor tab: your system is ready to brew
    the Doctor tab
  13. 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.

    Slide text
    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
  14. 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.

    Slide text
    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
  15. 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.

    Slide text
    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
  16. 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.

    Slide text
    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
  17. 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.

    Slide text
    install now on macOS 26, learning the commands, or setting up Macs for people who avoid Terminal
    wait custom Homebrew folder or extra package sources
    skip you already live in Terminal; take brew.env
  18. 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.

    Slide text
    brew install --cask homebrew-app
    macOS 26 and later · Swift · AGPL github.com/Homebrew/BrewUI
    the .pkg download also installs Homebrew if your Mac lacks it
  19. 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.

    Slide text
    your .zshrc or brew.env
    new repo tomorrow

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built with ❤️ in New York