package mismanagement: mac homebrew

by popular demand, I am finally expanding on my occasional fediverse post about how terrible brew is for Mac OS package management.1

But also, a few caveats:

  1. I am a curmudgeon. I do not give a single fuck.
  2. Don’t try to persuade me to use brew. see (1).

Many of the things that I am about to mention might have been fixed in the five years since I last installed and used it. I still don’t care. Like Manjaro the record is so bad that nothing is going to win back my trust.

I also maintain n, a version management tool for NodeJS on MacPorts, Signal-Desktop on Void Linux, and help update other packages for both projects as needed.

$ curl | sudo bash until you’re drunk

Let’s start out with installing homebrew following the default instructions2:

/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
  1. it asks to elevate permissions to take over /usr/local and change ownership on everything
  2. it clones the entire homebrew brew repository because they’ve apparently never heard of git’s --depth flag. what good does it do to have the ability to run brew 0.01?
  3. it builds brew from source. Admittedly it relies on MacOS’ (ancient) builtins instead of requiring a full Xcode install—this is one advantage, at least when installing it.
  4. it flashes a few messages about documentation—and oh also that it’s sending data to Google Analytics by default!3

$ hey google [analytics]

There is a lot of value in understanding what packages are getting used by which systems if you maintain packages. I have been known to look at the stats for Void’s Signal-Desktop package and MacPort’s n port. For the former, there are 12 Void machines running it, for n there have been 2 installations in the last long while, I think both of them are my machines.4

But the difference between the pretty basic stats that both Void and Macports have and the stats that Homebrew collects: homebrew acts as if it’s better to sin first and ask for permission later. MacPorts requires running sudo port load mpstats, Void requires installing popcorn and enabling the service.5 With both Void and MacPorts, you retain what I thought was a pretty basic principle of free and open source software: the ability to choose what happens on your machine.

Unlike on Void or MacPorts, Homebrew rolled out analytics silently. Instead of really handling the discussion well, it went about as poorly as you can imagine.6 And I’d bet the overwhelming majority of brew users still have no idea it’s happening—it’s an easy to miss message you see once! It also raises questions about the quality of the community that many of the people involved in that discussion are still there, ie., the person who added in gAnalytics originally.

$ brew install yolo

So now that we’ve got brew installed, what can you do? well, whatever you want! You don’t need to use sudo to actually install things! You’re a Power User, you know what you’re doing!7 Except when you don’t. We’ve all been there with an errant and disastrous off-by-one-keystroke command. For someone like me, using sudo is a little speedbump—a chance to make sure I’m sure. Brew, by making /usr/local (or /opt/brew on apple silicon) user writeable, hands you a RedBull and says ‘gun it.’

The question of whether or not it’s a risk in and of itself to make those folders user writable has been litigated enough already.8 I, obviously, think it’s a bad decision. More concerning is the fact that brew lets a lot of stuff in with what seems like little vetting. Hell, until 2021, you could get stuff automerged on github.

$ sudo port install sanity

So what’s my brilliant alternative? Well, duh, it’s MacPorts. Macports, which requires sudo. Macports, which deeply sandboxes its builds when installing from source.9 Macports, the one that has a small but tight-knit community of people who plain old give a shit in a way that the more corporate, emojified homebrew doesn’t.

yes, it requires a full Xcode install. Yes it will take up more space. yes, if you’re building from source it will pull in its own versions of whatever compiler you might need. But storage is cheap and you can do other things while xcode installs.

$ slip into some jorts

I’d be remiss if I didn’t also mention my friend june’s jorts system. jorts is beautiful and clever in its simplicity. Unfortunately, it doesn’t include a lot of things I use every day. But for a lot of people, I can imagine it’d might be enough.

There is a world in which I actually bother to fork jorts and run it using mercurial instead of git. but…only so many hours in the day.

edit: june mentioned quite rightly that the point of jorts is that she was tired of the shortcomings of pkgsrc, NetBSD’s ports system, hates the fact that brew doesn’t really manage dependencies very well (ie., it doesn’t track dependencies vs. requested packages), and as best I recall, disagrees with some of the choices MacPorts maintainers have made with packages she and I both use (e.g., MPV).

$ man -k ports

agree that Homebrew is terrible but Macports is too much and Jorts too minimalist? well, you have even more options!

  • pkgsrc which is NetBSD’s package manager but on MacOS and Linux
  • fink, the OG MacOS package manager which uses debian’s dpkg and apt on the backend. Pretty nifty but they’ve have trouble getting compatibility with > MacOS 10.15 working.
  • rudix which was brought to my attention today and looks pretty cool, unfortunetely it seems to be in decline, when judging by Github commits.

$ tldr post

Homebrew has sketchy security practices and runs google analytics by default. MacPorts doesn’t. Even if Macports doesn’t have everything I might want, the tradeoff between occasionally ‘just’ installing something with cargo or pip is fine.

$ exit 0

Just like Mercurial, MacPorts “lost.” That is to say, like git and fucking github, homebrew is so dominant that it is hard to imagine a world where it isn’t the default for 99% of people. For the short to medium term, it probably will be that way.

But fuck that. Use jorts. Use MacPorts.

a better world is possible.

see also


  1. well, Ruth asking me to expound on what I mean by “stop using homebrew jfc” ↩︎

  2. Tested on a 2014 MacMini running MacOS 12 ↩︎

  3. no, it’s not a joke: docs.brew.sh/Analytics ↩︎

  4. Void’s popcorn system dumps out a big JSON file, MacPorts has a little bit tidier system for stats ↩︎

  5. Somewhat ironically, popcorn is written in Go which is probably (read: almost certainly, it’s Google, after all) going to add in telementry ↩︎

  6. Saagar Jha’s blog post summarizes this debate nicely. ↩︎

  7. even if brew did require elevating permissions, I wonder what percentage of homebrew users have have NOPASSWD set in their /etc/sudoers file ↩︎

  8. eg., “how Homebrew invites users to get pwned”, this Stack Exchange discussion or this one ↩︎

  9. yes, MacPorts does have binary releases too. ↩︎