zerobrew is a Rust-based, 5-20x faster drop-in Homebrew alternative
68 points by lucasgelfond
68 points by lucasgelfond
zerobrew takes a lot of ideas from uv - packages live in a content-addressable store (by sha256), so reinstalls are instant. Downloads, extraction, and linking run in parallel with aggressive HTTP caching. It pulls from Homebrew's CDN, so you can swap brew for zb with your existing commands. This leads to dramatic speedups, up to 5x cold and 20x warm!
This project has no license.
Also, no mention of this in this thread. However;
This repo is built for parallel development by multiple agents. Read this before touching anything.
https://github.com/lucasgelfond/zerobrew/blob/main/dev/AGENTS.md
It's also 7 days old, if the git history is to be believed. (And mostly coded by LLM agents, as you mention!) There's no way it should be turned loose on a machine you care about. And the only indicator of that in the readme is "Experimental" in the status section, at the very bottom.
The young, experimental status deserves to be in bold at the top, IMO, regardless of how concerned you feel you need to be about license or slop issues.
The license is a monstruous amalgamation of all the licenses in the big ball of stolen code used for training Claude Code, I suppose.
I thought that many Homebrew's packages have to live in /opt/homebrew/ because directory names like /opt/hombrew/etc/tmux or something are compiled into the binaries (or maybe Homebrew compiles in dirs from the cellar like /opt/homebrew/Cellar/tmux/3.6a/etc? I'm unsure, this has some relevance to whether it'd be possible for zerobrew to use /opt/homebrew). See e.g. all the notes about "pick another prefix at your peril" and "The main reason Homebrew just works is because we use bottles (binary packages) and most of these require using the default prefix" from https://docs.brew.sh/Installation#untar-anywhere-unsupported.
Does zerobrew always install everything from source, or do you have your own binary cache to support the /opt/zerobrew installation dir, or do you do something else?
Many of Homebrew's bottles (meaning binary packages) are relocatable, but a significant minority aren't. There have been attempts (and I commend them!) to build a faster Homebrew before, and they typically get up to the 95% done point before running into all of the annoying edge cases that Homebrew has built scar tissue around over the years.
Source: Homebrew maintainer.
Edit: See sps1 for another recent example of this. I think these attempts are very cool, but Homebrew is for a handful of reasons unusually hard to lift into a different language!
Homebrew is for a handful of reasons unusually hard to lift into a different language
It doesn’t have to to get faster. In a recent blog post, Andrew Nesbitt showed that most of what makes uv so fast is language agnostic. I have no idea how much of that can be applied to Brew however.
I have no idea how much of that can be applied to Brew however.
A lot of it can and has been applied to Homebrew! brew itself is a lot faster now than it was 3-4 years ago, particularly on hot-path operations (like checking the prefix, fetching bottles in parallel, etc.). The parts that are harder to speed up are architectural (Homebrew fundamentally needs to pay the Ruby interpreter startup, needs to import a lot of things, papers over OS gaps by shelling out to bootstrapped tools, etc.). A rewrite can avoid paying some of those architectural taxes, but not all of them; critically, it’s unlike Python in that there’s no body of standards that describe how formula installation should behave, so Homebrew’s installation requirements reflect the constraints of Homebrew itself.
I use pixi global install for installing software on my Mac, which uses the conda approach of baking in placeholders. They're not re-locatable after install, but the packages are largely installable to any directory.
Baking in placeholders? As in the binary contains a placeholder string and the installer replaces that placeholder in the binary with the install prefix (presumably padded with zero bytes)? That sounds brittle... can we be sure the binary doesn't contain the install prefix's length anywhere? Don't compilers possibly optimize strlen("some string literal") into a constant?
It’s resilient to this problem by using a very long placeholder and padding the replacement.
When you saw Pixi, do you mean this project? https://pixi.prefix.dev/
Asking so I understand your approach and usage. Thank you!
I think these attempts are very cool, but Homebrew is for a handful of reasons unusually hard to lift into a different language!
I’d love to hear more on this, both as someone who has studied some portion of Homebrew’s internals (out of curiosity) and someone who works on package manager-y things. :)
A bunch of Homebrew bottles these days are relocatable, but I’m pretty sure an equal amount aren’t.
I dunno about hardcoding, but when using Homebrew on linux, it installs in /home/linuxbrew/.linuxbrew and that causes its own issues when on an selinux system, but it doesn't touch /opt. I think the linux bottles are built with that path if it is hardcoded.
I think the linux bottles are built with that path if it is hardcoded.
That's correct. /opt/homebrew is the path for ARM macOS. Intel macOS Homebrew used a different one (/etc/homebrew? I don't recall). And linux uses /home/linuxbrew/.linuxbrew.
/usr/local as seen here: https://docs.brew.sh/Installation#:~:text=%2Fusr%2Flocal%20for%20macos%20intel
Is Homebrew's speed, or supposedly lack thereof, really a problem?
Yeah, surely no one wants slower software, but I just don't see the comparison to uv as useful.
uv means: "I do this all the time, for all the projects, I reinstall them on many machines, in containers, whatever, also CI"
homebrew means: I have one work MBP and it has things installed. I update them once in a while and as long as it works, whatever.
For the standard homebrew use case it is not at all but an order of magnitude speedup may potentially unlock entirely new use cases?
It is, a few times a year, for me. Usually when I'm trying to grab a new tool, and it depends on something that many other things on my system depend on, then something needs to be built from source, so the build dependencies all need to get upgraded, then anything else built with those needs upgraded, etc.
I've had the act of adding or updating one thing take 45 minutes before on a fast mac.
That said... I might be an uncommonly bad case. My brew environment might be in xkcd 1987 territory. And I doubt this tool will help much here.
I use GitHub codespaces / devcontainers, often in repositories where I don't control the configuration, and my dotfiles rely on brew to install my tools. So, yeah, it's relevant.
For me speed was never an issue with homebrew in the sense that I don't mind it being slow because its so reliable and easy to use ..YMMV
As much as the author is honest about his use of AI to code. I trust it less to install it on my machine. I have used claude code before And I see the mistakes it makes so I would never trust a project built with it.