Homebrew is great on Linux
(Originally from October 2023, updated September 2024)
I'm a strong believer in the next generation Linux desktop model - which splits what is typically one monolithic system into different layers. This has been great for us at Universal Blue because it allows us to reuse Fedora's OCI images to deliver a more reliable and customizable experience for users.
However some users struggle with the concept of running workloads in containers. They're used to sudo apt install npm
and whatever tools directly on the host. We used to recommend setting up distrobox as your main user interface, this method has some unfortunate drawbacks:
- Users need to set it up this way. We ship some great distroboxes that we manage with podman quadlets. This is great for container nerds (wolfi forever!)
- There are UX problems that aren't being actively worked on. Ptyxis really improved the UX but there's still little gotchas that new users stumble upon.
- There's a mental leap that non-cloud-native developers must make that they don't appear to be making. Then they end up shelling into containers regularly and using it like a mini VM instead of how everyone else does it.
- It is useful for some folks though, but if you don't want to care about containers, then you shouldn't have to!
On the last point, when you're in a distrobox it makes managing podman containers for development different than just about anything else. This leads to unfortunate situations like this thread where the user thinks that you're supposed to interact with the system service inside the container, and the "preferred" solution ends up being a layered package.
If you're thinking "Why don't they use the linuxserver/syncthing container that has over 100 million pulls?" ... I found myself thinking that too but that's a problem for another day.
Enter homebrew
I typically don't follow brew, it's that weird Mac thing right? It ends up that about two years ago they switched to using GitHub Packages. This might seem like not a big deal but then as I read on it became clear that homebrew
is just using OCI artifacts as a package manager. Here's the neovim package.
It gets even better for us Linux users – the analytics are completely open and the user can opt out if they wish.
This is nice for people getting started on things like Fedora Silverblue because usually they just want to install htop
or whatever other tools they're looking for without the complexity.
Features
It's nice that the packages are maintained by both MacOS and Linux people, it's a much larger community, and you have the same toys as your Mac friends. They have just about everything. We've gotten direct feedback from Bluefin and Bazzite users that there's value in having the same package manager as they have on their Mac when they are experimenting with Linux. And you can do declarative config via a Brewfile
if you want to do that.
The network performance is awesome because it's just hosted on ghcr.io, It's also straightforward to set up a pull through cache on your network using any OCI registry you want if you miss that apt-cacher-ng
lifestyle.
- It lets people install packages who don't care about containers. "I just wanted to install neotopfetch!"
- It's self contained in
/home/linuxbrew/.linuxbrew
and can easily be blown away - doesn't interfere with the system - It has just about everything people could want in there
- There are lots of linux users, not even close to the number of MacOS users but that's more than enough.
- It's mostly GitHub native, there's lots of automation. Here's dysk being upgraded. You can observe the packages being built in GitHub actions and being pushed to the registry.
- The packages are just OCI blobs stored on ghcr.io, same place the OS is, making caching locally awesome and avoiding distro mirrors entirely.
- brew will keep everything up to date for you and is aggressively updated.
- The OpenSSF and homebrew are collaborating on implementing SLSA build level 2. Built in sigstore integration, just like my system images? Hell yes I'll take that!
From a sustainability standpoint it's lower risk for me to depend on homebrew than distribution packages. In 2024, Ubuntu's universe
repository is a liability, brew's investment in automation is a killer feature. FROM ubuntu:24.04
is always there for when I do need a distribution package, along with every Linux package anyone could ever need.
But no Linux ARM
Unfortunately there are no ARM linux binaries yet, but GitHub has ARM builders now, so it's probably just a matter of time. You also lose points with the gatekeeping Linux types for not using a "proper" package manager, so maybe that's actually an advantage!
A great compliment for Flatpaks
People keep trying to shove CLI applications into Flatpaks for some reason, even though it's not designed to do that. Now just about any CLI tool is at your fingertips. It's maintained by a well structured community, and I love that they have GitHub sponsors, it only took me a few seconds to send them some money.
And crucially both Flathub and Homebrew publish their usage analytics for everyone to see. No hidden numbers.
Caveats
The default installation of Homebrew puts it in your system path. This can lead to some unfortunate issues, if you brew install ffmpeg
this will pull in p11-kit
, and adds it to the path. And then Flatpaks stopped working because that library was preferred over the system one. Here's how we workaround that by setting the path only in interactive terminals.
And there are some things that aren't as clean as they could be. Having to ship gcc
on the image isn't ideal, but the brew ecosystem of packages is just too useful to ignore.
Depending on your distribution you may need to adjust some resource limits. Here's what we're shipping.
My default
Having it be an OCI blob is the thing that makes this really nice. My OS, my devcontainers, and my CLI tools are all hosted on a registry.
- Operating System: image based, no need for the user to use a package manager
- GUI apps: Flatpaks via the GNOME Software Center or KDE Discover
- CLI apps: Homebrew
And for the developers that's the usual, standard OCI containers. VSCode with devcontainers is my preferred recommendation since it's already a popular choice, and of course, toolbox and distrobox (as well as raw podman/docker) is also available so you always have other options.
With this combination you have access to nearly all packages from everywhere - we ship this setup with both Bazzite and Bluefin out of the box and it's been a great UX so far.