FR version is available. Content is displayed in original English for accuracy.
Today, I’m proud to announce Homebrew 6.0.0. The most significant changes since 5.1.0 are a new tap trust security mechanism, the new faster, smaller, default internal Homebrew JSON API, sandboxing on Linux, better defaults informed by our user survey, many brew bundle improvements, improved performance and initial support for macOS 27 (Golden Gate).
Happy to discuss any questions here!

Discussion (131 Comments)Read Original on HackerNews
Most Linux package managers cannot separate user-installed packages from system packages. This makes cleaning up your workstation nearly impossible and a pain in the ass, since you can't tell what should be removed, or more importantly, what can be removed.
Also, most native package managers update much slower than Homebrew, meaning you often only get outdated packages.
And because of pinning versions to LTS releases on certain Linux distributions many times those packages stay out of date for years. Which is quite annoying.
It's also quite stable, which you'd think more people would prize given the recent and on-going supply chain attacks.
Funnily Mise does not support dependencies, and I was quite surprised that it mostly doesn't matter, as either pnpm/uv handles that, or it's a static binary that just works. In the past, had the unfortunate experience of packaging a Python application for Homebrew (the ridiculous process involved importing around 50 dependencies as "resources", building every single one from source or manually checking if it's already on Homebrew, declaring build toolchains for 5 different programming languages as dependencies, waiting over an hour for CI to finish on every update, then an upstream update introduced a "build-time dependency loop" and the project suddenly became unpackable for Homebrew) so I totally get why Mise took the "easy way out" and just relies on language-specific package managers directly.
Only thing from my Brewfile that I couldn't replace was the Docker CLI (needed to interact with Colima). And I still use Homebrew for casks. I encourage others to experiment with their dev setups, there are some amazing new tools out there.
Also using brew for casks, and I think there’s a couple tools I couldn’t install with mise (e.g. pngpaste and zbar for scanning QR codes from screenshots).
This is intentional as mise is not intended to be a full bootstrapping solution in the way homebrew/nix is, mise is designed to be an overlay on top of existing systems. So if you want to manage python with brew and black with mise it basically just works without extra configuration. I think this design decision has paid off in spades. It sounds like a drawback but at the end of the day it's probably the #1 reason users find mise easy to use.
Projects then have their own dependencies, e.g. https://github.com/i-am-bee/agentstack/blob/main/mise.toml
Mise also has a task runner which automatically uses correct tools. Onboarding a new team member is super easy now, they just need Mise, "mise install" and they're up.
pypi, npm, and even github (through releases) are registries.
curl | sh is an anti-pattern. It passes no security check.
We are not many [1], but Homebrew has been a great way to quickly bootstrap an environment in immutable Linux distributions.
Note that certain operating systems such as Universal Blue's Bazzite (1.28%), Bluefin (0.49%) and Aurora (0.28%) default to bundling Homebrew [2].
[1] https://formulae.brew.sh/analytics/os-version/365d/
[2] https://github.com/ublue-os/brew
For example, there might be layers for “system” (core components), “environment” (display manager, DE, etc), and “user”, each of which are maintained fully separately so they can’t ever step on each others’ toes and break things. Yes, it means there will be some redundancy but for all the trouble and complexity it’s saving I think it’s a worthwhile tradeoff.
I've since moved my desktop box to NixOS, where everything is just flakes, but my mac runs circles around it so it's just there for Steam nowadays.
This has gotten better in recent years with user namespaces but it takes time for it to be adopted and achieve parity with what used to be just jumping to a user who can only write to a newly created dir in tmp.
https://www.gnu.org/software/stow/
https://xstow.sourceforge.net/
> The concept of a "userspace package manager" is something I would expect Linux to have figured out twenty years ago.
Each one uses their own package manager right?
What I hate is that e. g. debian puts me to conform to their FHS. I want things installed into versioned AppDirs. GoboLinux allows that; NixOS to some extent too (though they used hashed directory names). Debian does not allow me to do that. I don't want to conform to what others wrote; I want software that adjusts to my wants.
> Flatpak is more oriented towards GUI apps
Have they not recently added a mandatory systemd dependency? I can't use software that things it must force software I don't need or use onto me.
- Brew seems to have better support for the packages it has, compared to Nix where it seems a percentage of packages are not as well maintained,
- Better Mac support; some Nix packages have features disabled on macOS, I think just because the maintainers of this packages don’t have a Mac for testing,
- Better UX.
Obviously I miss the reproducibility of Nix environments and the ability to easily create my own flakes with specific packages, but on the balance, Brew has won me back. (I still like Nix, and FWIW we use Nix at work.)
Forced upgrades are not nice.
The only people I want to trust to quickly ship new code to my machine are Apple and my browser (which handles more untrusted input than anything else).
For everything else (vscode and its extensions, npm, homebrew, and all the apps that self-update), I prefer to err on the side of waiting a few days.
Some exceptional 0days might warrant a cooldown bypass, but even in its current form users are vulnerable to 0days until they run brew upgrade.
Also, where we package things from NPM/PyPi/RubyGems that have been subject to these attacks: we already apply cooldowns for you both when packaging and when creating PRs to update to new versions.
Relevant parts for those who have cool-downs at the top of mind:
> Across Homebrew’s history far more users have been protected by shipping zero-day fixes quickly than have been exposed to npm-style token-theft or crypto-mining attacks, so a global cooldown would be a net negative for most users’ security. The deeper reason Homebrew does not need a general cooldown is that, unlike language package managers, it already separates publishing from distribution: an upstream release does not reach users until it has passed human review, CI and checksum verification, which is the very review window that language-ecosystem cooldowns are trying to recreate.
[...]
> For ecosystems with a track record of fast-moving supply-side attacks, Homebrew applies a download cooldown: a freshly-published upstream version is not adopted immediately, giving the wider community time to detect and report a malicious release before Homebrew users are exposed. Cooldowns have been added for:
Your doc says "Human review of each release." What does that actually entail?
uv had a release at 10:21am yesterday with 7,060 additions and 2,409 deletions. The new release was available in homebrew at 11:46am. What human review happened there?
I don't know of any other OS package manager that ships code this quickly to users. Arch Linux has not pushed the new release of uv yet, for example.
If the ask is "who reviewed the diff": yes, a human didn't do that. That's not actually happening for all packages in any meaningful large ecosystem. I'm still unconvinced a cooldown solves that until e.g. we have an open source security scanner that runs on all Homebrew packages and requires a cooldown. Even in that case, my suggestion would be that we just run it in our own CI and block package release.
For those who don't know what broxit is talking about, they're referring to something like --minimum-release-age/minimumReleaseAge in many pieces of software and package managers to reduce vulnerability to supply chain attacks. Often times, such attacks are detected within a few days of compromise.
Here's Bun's, as an example: https://bun.com/docs/pm/cli/install#minimum-release-age
It annoyed me this week because I only had a few minutes to try elixir 1.20 after the announcement, and brew lagged behind. You can install erl and elixir by other means (I prefer to run my own toolchains) but it wasn’t worth doing in that moment.
Brew has or used to have a source option for some recipes and that basicallllly solves it too, if you squint.
> Cooldowns, livecheck and bumping
I know supporting Intel is an ordeal and a choice, but I'm firmly on the camp that Homebrew should find a way to maintain Intel support as long as possible.
If you want Intel support, MacPorts still runs back to Leopard.
If only Apple put a fraction of its resources towards maintaining something like homebrew (or paying the people who do), maybe the situation would be different.
I just ran the upgrade to 6.0.0, and it downloaded so many things concurrently that it killed my wifi (old router). Is there a way to cap bandwidth or maximum concurrent connections? (this is something I have to do in many download heavy apps, e.g., steam)
HOMEBREW_DOWNLOAD_CONCURRENCY
On another note, to commenters here, I've been using brew bundle with the Brewfile more and more these days as a declarative list of all user packages installed, should I just move to Mise or Nix instead? What are the benefits and drawbacks? Last time I used Nix on my MacBook a few years ago it seemed to brick my whole system so not sure what that was about.
[0] https://github.com/lucasgelfond/zerobrew
Speaking of important things.
I'd consider donating, but I find that behavior to be part of squeezing free computing and participating in and advocating for the corporate erosion of ownership of one's hardware environment.
I just threw them a small donation for supporting this software for so long, even if it's only 98% how I'd want the project to be run all these years myself.
Most Linux package managers cannot separate user-installed packages from system packages. This makes cleaning up your workstation nearly impossible and a pain in the ass, since you can't tell what should be removed, or more importantly, what can be removed.
Also, most native package managers update much slower than Homebrew, meaning you often only get outdated packages.
Isn't that what dependency detection does? Whenever I'm not sure if something can be removed, I just try to remove it, and if it would break something else, the package manager tells me. I can broaden my scope and see if that's also an unnecessary dependency for something and follow the chain, with it eventually ending up with a set of packages where I actually get the prompt to proceed or not (meaning nothing in it is a required dependency for anything remaining), or I see a package I definitely want to keep around and stop. If I'm interested in what's part of the base system, I just check the metapackage for the base system.
This doesn't sound like something that's a problem with package managers in general compared to maybe some distros just using them poorly.
I noticed that homebrew updated _all_ my casks when running 'brew upgrade' (even those with "auto_updates: true" in their Cask JSON API).
Is this intended, new default behavior? This did not use to happen...
See also: https://docs.brew.sh/FAQ#why-arent-some-apps-included-during...
I read this as "This means if you close your eyes you don’t see things, which is a bummer."
When you instruct the system not to tell you things, the system not telling you those things is a bummer?
If I could get more of the tech I interact with to stop doing things I didn't ask it to, it would reduce a lot of stress and wasted time.
It's probably discussed somewhere but didn't find when glancing at the OP.
I discovered Homebrew now sometimes asks whether I actually want to install a formula (e.g. `brew install ffmpeg` asks whether I want to install it because it has dependencies). Is there a way to disable this behavior and revert to the previous one?
—-no-ask, —-yes, -y or HOMEBREW_NO_ASK=1
https://github.com/Frizlab/frizlabs-conf/blob/663e287eadadd9...
I'd use it today on Linux, but I'm pretty anal about only using software from the distribution repos (or compiled locally if not available.)
For others still using Homebrew: a lot of work has gone into upgrading only when we absolutely have to and showing these upgrades to the user before we do them, including in this release.
thanks for all your work!
1: https://docs.brew.sh/Support-Tiers
- `formula@version` packages
- `brew version-install` (which uses `brew extract` and `brew tap-new` under the hood)
- `version_file:` support in `brew bundle
- `brew pyenv-sync`
I also applied and don’t get a job at Google (and various other places over the years) but never really bothered me that much.
Ironically I think I’d probably never have started working on Homebrew if it had.
I am using my own custom "package" manager in ruby, but naturally it is nowhere near as sophisticated as homebrew. I am looking more towards complementing this, but these days I also lack time for more thorough testing, so I try to minimize pain points (and thus also less frequently use software written by others for the most part, unless it is a key project such as libreoffice and what not).
That was when I realized Homebrew is much, much harder.
Your server needs to implement the git protocol. You can't just stick it on some server with a CDN in front of it, you need to run and fortify a git server.
Strange choices IMHO.