Ask HN: Best Alternative to Homebrew in 2021?

271 points by pchm ↗ HN
Yesterday I ran `brew install virtualenv` and homebrew decided to upgrade postgres, ruby, youtube-dl, vim, rust, wget and 50 other unrelated packages. The single command took 45min and broke all of my local postgres databases (and who knows what else).

At this point I should know better than to install postgres via homebrew, but unwanted/unasked-for upgrades is not a feature I'm looking for in a package manager.

What's your experience with other package managers for macOS? Currently looking into macports & nix and not sure which one to choose...

313 comments

[ 3.0 ms ] story [ 285 ms ] thread
I cannot remember why, but I chose pkgsrc (https://pkgsrc.joyent.com/install-on-osx/). It is however of varying quality.
I too only used pkgsrc when I had a Mac developer machine. Afaik mostly because of their superior dependency management.
I have also used it. I switched once homebrew installed conflicting versions of OpenSSL and wasted weeks of time trying to get both MySQL and vim working at the same time.

It is rough around the edges as some packages are missing if I remember right.

Macports
Yeah, macports still works fine. It has an equivalent to the OpenBSD flavors and does versioning fine. The only pain point is OS upgrades.
And the fact that it "needs" Xcode installed.
If my pre-coffee memory is correct, Macports only needs command-line tools for XCode.

    xcode-select --install
That said, MacPorts is often opinionated, e.g. they package certain versions of some software and not others.
It does not, it does need the "command line tools" installed. Certain ports require full Xcode but not too many.
One should bear in mind that it seems MacPorts takes a much more puritan approach to packaging than Homebrew, as this 18 month old ticket asking for awscli v2 (and its comment thread) shows: https://trac.macports.org/ticket/60452

I didn't dig into the process for a user to add their own ports, or share new ports with a team, in order to more fully compare the two packagers, but that ticket stood out to me

I don’t get how that thread demonstrates what you say. It just looks like awscli 2 is a pain to package; what am I missing?
Well, one will observe that brew manages to package it, without any similar stone throwing about the project's "hatred for pypi" or other meta commentary. It seems every project has *some* kind of quirk, but if the packaging system pays that cost once, then its users get "brew install awscli" instead of waiting 18 months for the AWS team to "see the error of their ways" or whatever one is expecting to change about that situation

I apologize if "puritan" was too emotionally loaded of a word that hurt people's feelings -- I didn't think "strict" was the right word but maybe I should have used "opinionated?"

My read of that ticket is it's a bunch of people saying "this looks hard, I don't want to do it." But if someone wrote a (good) pull request, I expect MacPorts would accept it.

The thing about MacPorts is that it's a very community-driven project. Things happen when someone decides to go do them.

(Individual maintainers are sometimes opinionated, but I wouldn't say they speak for the whole of MacPorts.)

Seconded, I've never had a problem with Macports, it just works.
nix has a very steep learning curve, but I have been using it on macOS for a while now. Can’t recommend it enough. Even started using it on my personal PC, which allows me to use the same nix flake on both systems.

EDIT: Personal PC is running NixOS not Windows.

Nix does have a steep learning curve. But, you're also very likely to install most of what you want easily.

Some other downsides:

- Nix installations can take time. Nix packages can either build from source, or download from a binary cache. If it's not in the cache, it will build from source.

- Nix can take up a significant of storage space.

However, e.g. Nix is amazing at rolling back package installs; and installing a package with nix won't ever break another package installed by nix.

If you like the phrases "pure/immutable", "declarative", "functional programming", etc. then you'll like Nix. -- If those words don't excite you, then you'll not like Nix.

I didn’t think brew upgraded packages automatically? Just updated the index? Am I missing something here?
I believe a proper ‘brew update’ does indeed get ran when doing an install.
They have a separate env var with language that matches OP's experience:

    HOMEBREW_NO_INSTALL_UPGRADE
    If set, brew install will not automatically upgrade installed but outdated formulae
https://docs.brew.sh/Manpage#HOMEBREW_NO_INSTALL_UPGRADE (that's a fake hyperlink cause they don't put named anchors on their <li> for some reason)

updated with an actual hyperlink: https://github.com/Homebrew/brew/blob/3.3.2/docs/Manpage.md?...

Wow, terrible misfeature. Why is that the default? I could maybe understand it if it were just dependencies, but upgrading everything is insane.
It doesn't upgrade everything. It upgrades dependencies and dependents of those dependencies (which, admittedly, can feel like everything). It does this because the alternative is sometimes breaking things.

A "breaking things without this example": - you want to install something that depends on `readline` - the binary package for the thing you want requires the latest `readline` - this upgrades `readline` on installation

Now, we have a choice. Either we upgrade _everything_ that depends on `readline` that you have installed or we knowingly break some of the things you have installed that depend on `readline`. We choose the safer option by default.

If you leave it a long time between updating: you are more likely to have more dependencies updated which requires more dependents to be updated.

I'm inclined to agree, but it seems Ubuntu's solution to this problem with "apt install <package> [-y]" where you are presented with a list of dependencies that will get upgraded if you choose to proceed is a much better trade off.

The user can of course ignore the dependencies notice by specifying the "-y" flag to force an installation.

I hadn't actually considered it until you explicitly mentioned it, but yes: I'd bet a lot of the frustration when using brew would go down if brew just chose to _say_ what it was going to do, and _ask_ if that was ok, instead of assuming the user completely delegates that choice over to brew

I am aware of the "brew pin" command, and I do think it would have saved OP some heartache, but I think your suggestion of prompting before transitive changes would be the most pro-user way

That would be a breaking change for most scripts so would need to be optional (which feels less useful for people).
I see. That makes sense. Seems like the documentation for that environment variable could use some work, unless this behavior and the reasons for it already exist elsewhere. Happy to submit a PR if needed. I do try to `brew upgrade` at least once a day, so that probably softens the blow of these automatic upgrades and explains why I haven't run into many problems with them.

> the binary package for the thing you want requires the latest `readline`

Have you considered trying to install the latest version of the thing that would be satisfied with the `readline` you already have installed (if it exists), or presenting the user with a choice on whether to upgrade or abort the install?

I think a few years ago they made updating all packages on install the default for some reason
It changed a while back. Definitely surprised me in a bad way in the last year or two and I went through something similar to the OP. That said, I stuck the env variable in my shell setup and I would point out brew does include tooling to upgrade databases from one major version of Postgres to the next so you can get back and running (unless you have cause to stick with a certain version to match server setup, which is a bit of a pain).
The fact that homebrew is awful is one of the huge reasons I don’t use MacOS for development like all my co-workers. Instead I use Windows with WSL because the company won’t allow me a Linux laptop.

If I had to use a Mac my solutions would be to alway use Docker, a virtual machine, or a remote dev environment of some kind.

What’s an actual concrete example of a problem you have with homebrew?
Funny, I use Windows with WSL and the first thing I do when I set up a new WSL instance is get homebrew (linuxbrew) and install everything else through that if available.

apt/dpkg and any other package manager that scatters files all over the filesystem is just an absolute disaster that--if you do a lot of R&D tinkering--eventually renders a computer unusable after a few years. That's what happened to my first WSL instance; no apt command would work anymore because it had broken its own dependencies.

IMO this is so cringe and far from the truth. If you want a slow non-standard package manager they litters your computer and breaks things then that is Homebrew. If you want standardized installs then use apt/pacman/APK and just don't install a lot of user packages not in default repos.

Homebrew is one of the slowest package managers I've ever used.

> apt/dpkg and any other package manager that scatters files all over the filesystem is just an absolute disaster that--if you do a lot of R&D tinkering--eventually renders a computer unusable after a few years.

That was your experience. Mine is that after using apt for a lot of R&D tinkering for 3 years, everything runs fine. apt is global. Sometimes that's great and that's what you want. Sometimes it's not. Another way to keep that in mind is to think as apt as "bad at doing cleanup".

The thing is that you have to have a separation between things that you want on your system all the time, and things that you use for one or more projects. For the first, apt is perfect. For the second, usually that's where I use tools like nvm for node versions, languages package managers like npm, and also docker (which I use a lot for development databases).

For a backend JS project, I would install nvm, npm and docker globally, and then for the project I would use node through nvm with a .nvmrc, install packages locally with npm and use a package.json and package-lock.json, and run the development database with docker through a npm command, usually the latest PostgreSQL version. The link between the backend and database would be made with environment variables, because that's also what I use in production.

The difference between the global (apt) scope and the project (the rest) scope might seem like a failure of apt, but I personally see it as the difference between global and local scope in programming: both have their use, we separate them for a reason and we don't put the same things in them.

> apt/dpkg and any other package manager that scatters files all over the filesystem is just an absolute disaster that--if you do a lot of R&D tinkering--eventually renders a computer unusable after a few years. That's what happened to my first WSL instance; no apt command would work anymore because it had broken its own dependencies.

This is the craziest claim that I've ever heard about package management, I think

I would love to hear a more complete story

I hate that you are forced to sign up for an Apple account just to install XCode which is required for Homebrew which pretty much makes the machine useless.
This is not correct. All you need is the command line tools, which brew tells you to install with `xcode-select --install`. No account needed.
Oh shoot thank you, for some reason when I last looked it seemed it was implied you needed the whole Xcode package.

Guess I'll give that machine another go now.

I feel the same way. I've had a very good experience running xubuntu.
I don't even bother with WSL anymore, most dev packages I use comes as prebuilt Windows binaries bundled as zip-packages that you can unzip anywhere and run. No dependency management, no magic updates, no PPAs, run how many versions of the same software you like, delete folder when don't need it anymore. Super easy.

Granted I don't work much with compiled languages anymore so I don't need to setup some complicated tool chain, but when I need to do that I usually go for MSYS2 or WSL when it has to be Linux.

Can't tell if trolling, but either way, this is hilarious. Almost better than the OP, who's looking to switch the best (i.e. easiest to use) package manager on macos because of one fuckup which was 90% his fault (a) there's a cli flag you can disable auto upgrades with and b) who tf installs and runs postgres natively, what are you, from 1995?)

I mean, using Linux through Windows because you don't like homebrew? What the fuck dude.

I have no clue how you people stay productive, because if a package manager gets your panties in such a twist, I can't even imagine what your opinions on text editors would be, not to mention actual code & system design.

My experience is that both (Macports, Homebrew) are comically unreliable and frustrating to use. That said, with my insistence to install under $HOME, Macports seems to work slightly better. But truly, I got the best results from downloading and compiling every single flipping dependency myself.
Homebrew isn’t unreliable — I’ve used it for more than a decade with no problem. What’s an actual problem you have with it? Perhaps others here could help you.
I've never had a problem with Macports and am wondering exactly the same thing. "Comically unreliable"?!
There is no help for problems such as how the main developers seriously thought it was fine to have a user account own a shared system directory for many years, until Apple finally just took control over that at the OS level and forced them to figure out some marginally less borken arrangement.

Macports is a tougher sell for an average user today simply because the disparity in popularity means macports library is smaller and older. But macports is engineered more correctly.

> until Apple finally just took control over that at the OS level and forced them to figure out some marginally less borken arrangement.

This was my biggest complaint about Homebrew. Does it mean it was finally fixed?

It seems to install into /opt/homebrew/ now, whereas previously it used /usr/local.
I'll repeat what others have said above, but perhaps with more emphasis on the layperson's perspective.

I think I started using homebrew some 4+ years ago. I have no idea what a cask, tap, pour, or whatever is. At first things "just worked" and it was great.

Then came the couple of afternoons where I had an important project to finish, and I had to upgrade X. I think once it was matplotlib (for which I had to upgrade pip? ... I can't remember) or something silly like that. Everything broke, I had to reinstall all my python packages (that's when I moved to pyenv), and I did not finish my work on time. There was probably an easier way, but I was (am) a newb and I didn't know how.

I remember brew was one of the first command line utilities I ever used and thought, "woah, that was easy _and_ cool!", but I no longer think I am the target audience.

Someone might say the onus is on me to learn more about the tools I use, and they are probably right. I need to know my .tmux.conf or .zshrc or whatever to get the most out of those, too, and sometimes I like to dive in. For the most part, I just want to Get On With My Work and be oblivious.

If you could provide some guidance, I would genuinely be grateful. For a newbie like myself, when I see comments like "just set HOMEBREW_NO_AUTO_UPDATE=1" and then back and forth on why that does and doesn't work, I decide I don't have time for this today and cross my fingers I don't need to brew install anything in the near future. And if I do, I will probably avoid it (because it will take, I don't know, hours?).

The cask project supports large binaries and projects whose licenses are a little more poisonous than your standard brew libs. tap as far as I can tell is basically the same as PPA extensions in linux, it lets you install stuff from external repo lists. PPAs were pretty standard fare when I used to use linux more often, maybe working with package managers in your distro of choice for a while will help. In practice you usually don't need to use either cask or tap 99% of the time.
Thanks. I agree the onus shouldn't be on you to figure out how to do sophisticated things, and it should basically just work without breaking your system.

However! You shouldn't be using your system package manager to install Python dependencies! As you know, since you moved to pyenv. But I don't think it's fair to blame homebrew for getting you into trouble when doing that; one also wouldn't use apt to manage python packages.

In fact if you look at this thread, many supposed problems with homebrew seem to be in fact problems with python package management. It's the same with all languages isn't it -- ruby and rbenv and gem, node and nvm and npm, rust and cargo. As soon as you start actually installing 3rd-party dependencies, you're better off using something language-specific to install the interpreter / compiler / toolchain, better than using homebrew or apt etc.

> But truly, I got the best results from downloading and compiling every single flipping dependency myself.

My experience has been that very, very rarely is any installation as straightforward as "curl && ./configure && make PREFIX=whatever install", partially due to everyone in the known universe thinking they need some awesome new build system, partially due to unknown dependencies and their versions, partially due to it usually needing some patches because they only build on the author's machine, and all of that is just noise when I just want to have something running

The value of Homebrew to me are the constantly bumped formulae descriptors, definitely, 100% NOT the "brew" frontend for it. So, I've found a nice middle-ground by switching Homebrew into developer mode and neutering its bottle system and using "--build-from-source"

This isn't necessarily to lobby you, as much as "for your consideration" and to raise awareness for others that one need not throw the baby out with the bathwater just because the brew frontend is user-hostle

> My experience has been that very, very rarely is any installation as straightforward as "curl && ./configure && make PREFIX=whatever install", partially due to everyone in the known universe thinking they need some awesome new build system [...]

Aye, This is particularly impacting when the build system itself needs to be eh built.

> The value of Homebrew to me are the constantly bumped formulae descriptors, definitely, 100% NOT the "brew" frontend for it. [...] and using "--build-from-source"

I hadn't thought about that and I suspect you are right. Although I lack recent exposure to it and I can certainly recall getting very annoyed by it, I have to say that my experience with Gentoo's Portage/emerge is by far the least unpleasant as dealing with package managers goes.

I think, you don't need to choose any other package manager because homebrew is the most mature thing on macos. Just disable autoupdate when installing something: HOMEBREW_NO_AUTO_UPDATE=1 brew install <formula>
And since this technique relies on setting an environment variable, you can of course put it in your .bashrc/.zshrc, restart your Terminal, and you'll never have to remember it again:

  export HOMEBREW_NO_AUTO_UPDATE=1
Homebrew stinks of over-optimization and deletionism.

In contrast to how it used to be, Homebrew now seems designed for people that only want popular bleeding edge packages, and nobody else. If I just wanted to install google-chrome, sublime, and skype, I would use the app store. I used to use Homebrew to install more obscure packages that were useful to me, like Arduino, Processing, and some specialized bluetooth tools.

It is especially frustrating because there are good reasons to not want bleeding edge. OSX ages pretty well, and new versions of macOS often remove important features. As long as you have security updates, I think it is reasonable if you run an older version of macOS. For some of us, Catalina and Big Sur were pretty painful, especially if they are a liability for how you make money. Losing total-terminal and total-spaces were a big blow to my workflow, and not at all simple to work around, as well as certain accessibility software.

Homebrew being so aggressive about updating itself compounds many other issues it has. For one thing, major changes are made frequently, and it is very aggressive about pruning packages and only supporting recent version of macOS.

So, I have lost count of the number of times Homebrew has broken itself.

Homebrew will go out of its way to search through its history and tell you a package has been removed, but gives you no easy way to install them. Homebrew could make it fairly easy to revert updates, since so much of it is in a git repo, but it doesn't.

I wanted to install an SNES emulator, and I was using an install of macOS from maybe two years earlier, and Homebrew installed a version that was incompatible with my OS. Since it was a cask, I don't think anything depended on it. I had to actually search through the Homebrew repo history and check out that specific formula, since nobody had a tap for it.

Unless you are near the center of the bell curve, you don't matter. And it is a shame, because I really think that it wouldn't impose a significant cost to support more of us, and substantially improve its UX.

Homebrew used to be a powerful repository of most macOS software. Some of its less used packages could be unreliable, sure, but that was the case regardless of where I got them. Now it is morphing into an App Store. This is part of why I gave up on macOS two years ago and went to Linux full time. I can't rely on Homebrew.

I feel your pain, but can't help blaming Apple rather than Homebrew. They made an OS that users can't bear to upgrade because of removed features, homebrew is merely following their lead and focusing on bleeding edge users. Maybe the logic is: if you don't want constant churn you wouldn't be on a mac.
But Homebrew didn't used to be that way when I started using it. And with some fairly small changes it could go a really long way to supporting more users. TBH if I had the time, I would roll up my sleeves and do it myself.

The whole reason that I used Homebrew to begin with in 2014 was to help mitigate these problems.

I think there has been a cultural shift away from being more useful for a larger base of users, to being optimal and "clean".

The least it could do is confirm before it makes irreversible and sometimes breaking changes to your system. I don't see any good reason to delete your distfiles after potentially installing an incompatible package. And compared to most Linux based package managers, Homebrew makes big changes to its interface frequently, which makes it a headache to keep up with. Just look at how much casks have changed in the last two years.

Anyway, when I felt I could no longer rely on Homebrew, that was the last straw for me dumping macOS.

> They made an OS that users can't bear to upgrade because of removed features

I thought the story was that Apple had a problem with GNU licensing, and that was the reason everything got locked to ~2007 software, forcing everyone who wants to use bash and GNU utils to resort to a package manager.

Yeah… googling it, people have long been saying GPL v3 is what Apple has a problem with:

http://meta.ath0.com/2012/02/05/apples-great-gpl-purge/

https://news.ycombinator.com/item?id=18653485

What you're talking about has nothing to do with what GP said.

Apple cheerily breaks functionality for end users when they decide to remove or replace APIs on every major release of macOS. This tends to hit power users especially hard, as they often use tools that extend Apple's narrow facilities for things like handling keyboard input, managing windows, or controlling applications' audio volume through third-party tools that rely on internals of macOS that are not supposed to be public-facing, and those get broken more often. If your favorite tool relies on an API that gets pulled and doesn't (or can't) get rewritten when the new macOS release is in beta, you're SOL.

Homebrew breaking on macOS upgrade is also due to one thing that's fundamental to Homebrew's design, which is that it tries to rely as much as possible on that same external base system which Apple provides but destructively revises whenever it sees fit. (This design choice is apparently the author of Homebrew made because relative independence from the base system meant too much recompiling for him on Homebrew's competitors at the time.)

Package managers are used to install a hell of a lot more than bash. The idea that they wouldn't be necessary on macOS if only no popular tools were licensed under the GPLv3 is laughable.

(comment deleted)
If you have any kind complex toolchains, then a major update can be a real burden.

Just for me, using a customized desktop, iOS app development, and being a zfs user means that I had to set aside a lot of time for updates.

And beyond that, Apple has become really sloppy with new releases, and you're best off waiting at least six months for the major bugs to be ironed out.

(comment deleted)
You may be interested in MacPorts, which literally supports back to Tiger. (Some of the stuff they do to make this happen is actually nuts, e.g. https://github.com/macports/macports-legacy-support.)
Awesome, I will check it out.

In my case, it was in 2017, and I remember clearly what happened. Homebrew alerted me about the most recent compatible formula, and what commit it was removed in a week earlier. I was then forced to unshallow the Homebrew repo, revert that commit, and then I could install it. I remember I had a good reason for not updating my OS, and I'm sure it was less than two years old.

It was incredibly frustrating, and took a lot more effort than it was worth. Homebrew already had the ability to find the last good version, it would not have been hard to automate it. There were no taps at the time, I had no choice but to do it manually.

What's 'deletionism'?

Is it the act of being fastidious regarding everything under '/usr'? If so, count me in.

One of my biggest gripes with the aged Linux install ritual is having to keep the source bundle forever in case I ever decide to uninstall. Why? Because the autoconf makefile is the only rule that cleans up all the bins, docs, and shared files that were sprayed into the OS. Building from source needs an uninstall fix, but no one seems to care. (Or I simply don't understand how w/o keeping the build folder forever... Help?)

(comment deleted)
If you have an old version of a package, say OpenSSL, that was installed a year ago when you wanted PackageA, then both will be updated when you get PackageB which also depends on it. B’s bottle only refers to the new OpenSSL, and the old version is deleted so you need the new A bottle. No auto update just means you use the state of homebrew-core that you had before you ran the command, rather than updating it right before using it.

It makes sense, but then I don’t do full upgrades and get delayed just like OP. I live with it.

This looks like a really awful solution. Does homebrew not ask the users on each run whether they want update something and warns them about the dangers? Like a responsible software?
I just reached the same breaking point -- and normally I am pretty sympathetic to software jank, but the maintainer of homebrew is so actively hostile and rude that my degree of empathy is significantly less -- and switched to Nix, which is quite good, conditional on three gotchas:

1. Nix has very limited support for GUI applications of the kind that you'd find in `brew cask`. Not no support, some of them are there, but limited support compared to brew. If you use brew as an out-of-the-box install-everything setup like me, you'll not be able to replicate that easily with Nix.

2. Nix can't currently build Swift applications because of some Xcode something I didn't fully understand.

3. I found a small number of packages that are broken on Nix on my aarch64 / M1 MacBook Air (and marked broken, so when you try to install it complains) and a small number that are broken without being marked broken. In specific, I think R was one that surprised me -- this is a major programming language and although the build requirements are onerous (it's a mix of C and Fortran), I would think it would work.

That being said the actual process of installing, updating, and upgrading seems much faster and dramatically less shitty than homebrew, and so I recommend migrating stuff off of brew anyway.

What’s an actual concrete example of a problem you have with homebrew?
I know that there are usually workarounds to these problems, but they tend to be obscure, and change frequently, and are not simple to look up.

Pacman, apt, portage, etc have much more stable interfaces. But the workarounds for my edge cases in Homebrew from a year ago don't work anymore. Even knowing what is an edgecase or not is a problem.

Most of these issues would be fine if the interface changed as slowly and consistently as Linux package managers.

It’d be nice if it asked if it’s ok to remove old versions of dependencies when installing a new package. It’d also be nice for it to not upgrade, say, wireshark and nginx when installing, say, ffmpeg, without asking first.
You might be interested in `HOMEBREW_NO_INSTALL_CLEANUP` and `HOMEBREW_NO_CLEANUP_FORMULAE`. See `man brew` for details.
Yeah, I’m going to put those in my rc file. I’m surprised they aren’t the default options but that’s not a big deal.
`HOMEBREW_NO_INSTALL_CLEANUP` used to be the default. Many users complained about how much space Homebrew used, and were shocked by how much they saved by doing `brew cleanup`, so now it’s done by default.
I find Mike McQuaid pretty reasonable and forthright whenever I have ever messaged him. Also, he is hardly responsible for every formula out there.

For anyone who remembers the year 2000 and having to compile everything from scratch, Homebrew is brilliant - but there are complexities and quirks. For Python I’d go with pyenv. Postgres - well, watch your step and maybe use Docker instead.

For PostgreSQL on macOS I use and suggest https://postgresapp.com/ which is free and able to manage multiple Postgres major versions. It's also self-contained in a folder in /Applications. Also, version 14 of Postgres in the app has m1 native support.
For “infrastructure” apps like databases, caches, etc, I’ve been using Docker containers. Very easy to setup and tear down in a repeatable way. Unless I’m modifying the app itself, of course.
Exactly. I have a few build tools on my machine but any service installed locally has been long gone. Even the apps I work on - I just have the code locally and compile/package it up for testing within a container, which resembles the actual production landing spot. No more "it works on my machine".
For me it’s the only sane way to manage multiple small projects. A few lines in a docker compose file and I’m done, no matter the Postgres/Python/Ruby/Lib or framework version, everything is isolated and reproductible. Downside is gigabytes of RAM wasted.
I also tried Nix (as well as NixOS) but it's obviously difficult to use and has a very steep learning curve. But actually it might be the most flexible and stable package manager out there. So probably the problems mentioned can be fixed by custom configuration but that might require deep-diving into Nix and using Functional Programming for package configs... For some time I also used to just ./configure && make && make install (sometimes combined with stow) to my home dir, that worked also well but makes installing and upgrading tedious.

That said, I'm sticking to Homebrew. Not really sure about this auto-upgrading, maybe it can be deactivated, on the other hand probably it's a good way to keep packages updated.

I think the problem with Nix is that it is actually not a package manager but a build tool (that provides some package management utilities). People try Nix with the assumption that it should be as easy as apt-get (for example), but found tutorials with a block of code in a weird language...

Sure, you will eventually need to use the Nix language if you want to have complex and reusable configurations, but this is actually not needed for beginners! To install packages, you need the Nix package manager (with channels already setup) and use `nix-env` to install for the current user. You can just search for the package in https://search.nixos.org/packages and use the command directly.

If you want to have user configurations, use home-manager, just modify the example to add other options, you seldom need complicated Nix expressions unless you need to build a package by yourself.

When you really need to do so, you may want to have a look at other's build script, and make sure you understand everything in the build process, including compile dependencies and runtime dependencies, environment variables, etc. You may want to read Nix Pills at some point, but maybe you can get away with reading just the relevant section (incomplete knowledge, but usually enough to get the work done).

> I think the problem with Nix is that it is actually not a package manager but a build tool (that provides some package management utilities). People try Nix with the assumption that it should be as easy as apt-get (for example), but found tutorials with a block of code in a weird language...

Indeed, I've been using Nix for many years (on Ubuntu, NixOS and macOS), and I now find the apt-get style 'considered harmful'.

Instead, I define a single Nix derivation ("package") which provides everything I want in its 'bin/' directory, e.g.

    with nixpkgs;
    buildEnv {
      name = "my-macbook-programs";
      paths = [ bash gimp /* etc */ ];
    }
The nix-build command creates a symlink called `result`, so I put `/path/to/my/git/repo/result/bin` in my $PATH.
Just wondering, what is the benefit of doing this over nix-env for system-wide applications?

For project specific environments, I usually use `shell.nix` (maybe I should switch to flakes now) together with direnv that runs nix-shell automatically when you enter the directory.

For beginners to Nix, I think they should do the transition gradually, there are so many concepts in Nix that may be unfamiliar to them. I think getting a system to work quickly (maybe in a not so idiomatic way) is more encouraging than asking them to read Nix Pills and understand how packaging works in Nix :)

`nix-env` is an imperative command, whilst writing a .nix file is declarative. In particular, the latter can be managed using git, e.g. here's mine: https://github.com/chriswarbo/dotfiles/blob/41c5c4643845f437...

That's actually over-complicated, since I used to use nix-darwin and haven't bothered to un-pick it yet.

You could use nix-env to install the file with `nix-env --install --file default.nix` rather than using nix-build + symlinking the result.

What are the advantages of just nix-build, and adding the result/bin/ to path? Arguably, `nix-env --install` modifies the underlying profiles which manage symlinks. (nix-build + add to PATH is imperative invocation; but `nix-env --install` is and imperative invocation with a stateful effect).

e.g. of "how could that be bad?". I'd managed to get myself into a confusing state with `nix-env --install`. When setting up NixOS, I'd installed firefox as the root user. Months later, in my normal user account, I was confused why such an old firefox was installed (since my profile didn't install firefox). I can't remember exactly, but this also somehow caused problems with fontconfig. -- Probably easily avoidable; but if you don't know what you were doing, you might also try all sorts of install commands and forget.

`which -a` and `realpath` are your best friend when you're dealing with a multiuser package manager! Together, they make it easy to figure out if a package comes from your user profile, the default imperative profile, the system profile, or a transient shell profile
I also use Nix, and agree with these caveats. My personal experience is that it can be hard to initially set up Nix, but once you do, it's rock solid. It's particularly great for sharing config across machines. Here's config for my personal dev environment for instance: https://github.com/mjhoy/dotfiles/blob/main/nix/nixpkgs/conf...
I tried Nix while ago when NixOS made news in HN. You are right, it is difficult to set it up. Eventually I give up on it and tried to remove Nix from my macOS, let say it is difficult to remove Nix as well. I tried their command line to remove Nix and it didn't remove it even with sudo. Nix been sitting on my macOS for a month since it couldn't remove it completely. I realized I just have to go to Disk Utility to dismount/remove the Nix VHD and then ran the command line again which finally got it removed from my OS.
Hm, that's a good point.

Removing Nix is easier on operating systems where root is root (normal Unix-likes without a lot of filesystem-related security policies enabled). Nix only uses a separate APFS volume on macOS because Apple disabled writing to /.

The way that affects the uninstall process should be documented.

I spotted some people who've recently worked on Nix's install scripts and uninstall procedure elsewhere on the thread. You can file an issue if you think they'll miss your comment :)

Regarding GUI applications: you're probably talking about the Nixpkgs repository, rather than the Nix tool itself.

I use the following Nix function to install GUI applications https://github.com/cmacrae/.nixpkgs/blob/d4b51eb414b0edaffae...

It doesn't work for everything, but I use it at the moment for Amethyst, DBeaver, DockerDesktop, Emacs, Firefox, iTerm2, Postman, Slack and VNCViewer.

This is neat! I wonder if there would be value in having a repo for only GUI applications, equivalent to casks. I suppose it works best when the application doesn’t also auto-update, which many do.
> I suppose it works best when the application doesn’t also auto-update, which many do.

Yes, the update prompts get annoying (auto-updaters don't work since everything's read-only). I use niv to update things, e.g.

    $ niv update firefox -v94.0
That will:

- Update firefox's version field in nix/sources.json

- Update its url field based on its template (for Firefox that's "https://ftp.mozilla.org/pub/firefox/releases/<version>/mac-E...")

- Fetch that file to the Nix store

- Update firefox's sha256 field to match that file's

Running nix-build will create a new system package, and the nix/sources.json changes can be committed to git.

Yes, agreed. Someone asked if there can be a progress bar on Homebrew. Instantly shutdown the thread.

Homebrew is old and it needs to be replaced. It has served its time.

Homebrew is still here to stay. If Apple provide a package manager, then it likely that people will swarm to that but again it depends on how much capabilities and feature parity it have over other package managers. Microsoft is working on this with their Winget. Homebrew is great for casual and daily users since we don't have to keep hunting for software updates.

And Homebrew does have a progress bar for each app. The bar is for the downloading but other than that, I don't think it need a progress bar for installtion since they are quick to install than using the GUI installation.

Winget isn't really a package manager so much as an installer wrangler and frontend for the Microsoft App store. Of the nearly 30,000 manifest files inside the winget repo, fewer than 150 of them define a single dependency. The rest run executable installers that can do basically anything, or just grab an app from the Microsoft Store. It doesn't do anything to eliminate the chaos of every program doing whatever the fuck it wants to get itself installed or create a common ecosystem of integrated packages, which are the main points of package management.

Winget also lacks most of the core functionality of a package manager, including knowing how to uninstall anything at all. But uninstallation will never work reliably on winget anyway, as long as winget an installer wrangler, because installer wranglers inherit unreliable and bespoke per-package installation/uninstallation procedures from existing Windows apps. After a year and a half in public, Winget is still just Chocolatey but faster and much worse in every other respect.

There's basically nothing on offer on Windows if you want a package manager instead of just some automation wrapping executable installers. (Scoop is the closest thing, and it's sort of just now swinging back from the verge of death after months in limbo.) The fact that Microsoft announced a project and called it a package manager has done more or less nothing to change that.

> Homebrew is old and it needs to be replaced. It has served its time.

You are more than welcome to build your own alternative. Homebrew is open source and volunteer run. I'm sure there is a very valid reason requests like this get shot down.

No wonder open source maintainers hate dealing with people like you.

http://antirez.com/news/129

https://news.ycombinator.com/item?id=12000746

https://github.com/kossnocorp/etiquette

I don't hate it, I just think there is room to improve. Also, no need to accuse me of not understanding open source development. I am thankful to you and others, at the same time it is I think OK to say it needs to improve. Although, I believe like a lot of technology pieces that sometimes it is not worth improving - just start from scratch. There is a lot of baggage with Homebrew.
It seems this is the issue in question: https://github.com/Homebrew/brew/issues/9186

The maintainer did close they issue but they didn't lock the thread. If there was a very valid reason the request got shot down, it went unstated afaict. (Fair enough if they just don't allow feature requests on the issue tracker, I guess)

> Homebrew is old and it needs to be replaced. It has served its time.

Counterpoint: I've spent serious time (years) with, oh, six or seven package managers, in a couple decades of using package managers. More if you count Flatpack and stuff like that.

Brew is my favorite, all-around. Package selection is incredible. Stability is excellent. It's a little slow and I think defaulting to updating the package list damn near every time one invokes the command is a really weird choice, but that's configurable.

My second favorite? Docker :-)

Third would probably be portage (from Gentoo), I guess. Then apt/dpkg.

Worst I've used is easily Macports, and it's not even close—however, I switched years ago because it broke constantly under normal usage, on my machine, so for all I know it's great now—and I've never forgiven RPM-based distros for all the time I lost to RPM hell over the years, and for going so long with worse CLI tools than apt.

Void's seems very nice, but I've not spent enough time with it to feel the rough edges.

> I've never forgiven RPM-based distros for all the time I lost to RPM hell over the years, and for going so long with worse CLI tools than apt.

apt and dpkg are way behind dnf and rpm these days, both in terms of the structure of packages and the interfaces of the high-level CLI tools

What do you like best about Homebrew?

> What do you like best about Homebrew?

Some of its advantages are, in a sense, unfair, because it doesn't manage my OS or its most vital pieces, which is part of why it's never, in nearly a decade, broken my system the way any others have. Homebrew's never made my system unbootable. Homebrew's never broken my GUI. Homebrew's never fucked up some driver that had been working totally fine.

In another sense, that's totally fair if you consider the platform as a whole. It's really hard for Linux overall to separate user packages from system packages, mostly because it's all mixed up together in a way that it's not on MacOS or Windows—but a distro could take that approach, if they wanted.

So, that'd be one thing. #1: Separation of a very complete and capable base GUI OS from the rest of my packages, with the base OS upgrading in lock-step and very reliably, and everything else totally disconnected from that.

#2 would be the package selection. The number of times I've found some lowish-star-count project on Github, blindly done "brew install [guess at package name]" and had it work, is crazy. Non-free stuff? It's there too. AFAIK Gentoo and Arch are the only ones that even come close—but then you're stuck either hoping rolling-everything doesn't break your system, or trying to maintain a jenga tower of pinned packages and still risking breaking your system when you eventually do update them. I'm actually not sure there's a single piece of software on any of my Mac hardware, for work or play, that's not either, 1) from Apple, or 2) installed via Homebrew. And I've never added any kind of 3rd-party repo to it.

(a minor point: it's also nice that I can guess the correct package name more often with Homebrew than on Debian and Ubuntu)

#3 is that it has never, ever broken for me, under normal operation. An "install" or "update" or "upgrade" or "remove" has never broken my package manager itself, or its package database, or left its installed dependency tree so deeply fucked that I lose an hour or five un-fucking it (in fact, I've never seen that happen at all with Homebrew). OS upgrades have occasionally made me run a one-time fix to its directory permissions. Maybe that's happened twice in a decade of use? AFAI can recall, that's it. Macports borked itself badly under normal operation every 3-4 months while I was using it, while having a smaller package selection and compiling (=taking way longer) more often—this was, IIRC, like 2011, though, so again, it may be better now. Every other package manager I've used for any serious length of time, I've repeatedly seen get in weird states that required substantial fiddling before I could use them for anything again, after what should have been boring and normal usage.

(see point #1 for why it would also be a lot more tolerable if it did have that trouble, than it is when that happens on, say, Linux, and indeed, that's the only reason I was able to struggle along with Macports for a little over a year before switching—I could just rm its directory and start over, after the second time from a script that did it for me, without causing any harm whatsoever to my OS itself)

> Some of its advantages are, in a sense, unfair, because it doesn't manage my OS or its most vital pieces[.] [...] [T]hat's totally fair if you consider the platform as a whole. It's really hard for Linux overall to separate user packages from system packages, mostly because it's all mixed up together in a way that it's not on MacOS or Windows—but a distro could take that approach, if they wanted.

Yeah, this is a valid insight! It's essentially the approach that contemporary free BSDs take, and it's a direction popular distros are gradually trying to move in by shifting end-user applications to containerized package managers like Flatpak, AppImage, and Snappy. Fedora Silverblue is an example of an extreme case, where the base system is read-only.

> #1: Separation of a very complete and capable base GUI OS […]

I suppose the BSDs fall down here, since their base system doesn't include a GUI.

> Every other package manager I've used for any serious length of time, I've repeatedly seen get in weird states that required substantial fiddling before I could use them for anything again, after what should have been boring and normal usage.

I've only really seen this happen when using distro package managers to perform several years worth of release upgrades or convert between distributions.

I like the uniformity of Linux's package management tools (i.e., the ability to use the same tools to manage OS components as end-user software), but I can see how using one thing for OS components, especially if it's reliable and mostly hands-off, but then using something else for end-user software can be appealing.

Yeah, I think these days I'd find FreeBSD a better fit than Linux. I'm... increasingly kinda over Linux. Red Hat's continuing political success in pushing projects it (more or less) steers toward de facto standard status, while having (in my opinion) god-awful taste in project architecture and goals, has the whole ecosystem going a direction I don't like.

Nonetheless, it'd be nice to have the GUI included in the "this doesn't break" part of the OS. It'd be pretty unlikely that Homebrew could screw up an entire day for me, because the scope of things it's likely to even be able to mess up is limited. A package upgrade breaks X or Wayland, though? Ugh, there goes the day. Increasingly, I think stronger guarantees that the GUI layer does not break, or become unstable (god, I've seen so many X crashes in my life) except under very unusual circumstances, would be table-stakes in my switching full time to another workstation OS. Which leaves me options of... MacOS or Windows. Win10/11's telemetry and adware crap is unacceptable, and I like unixy tools, so that leaves me one option. :-(

Then again, ZFS with snapshotting can paper over a lot of packaging & system-update problems, which is part of why I'm thinking there may be a lot more FreeBSD in my future (yeah, yeah, I know, Linux has it too, but I've developed—like scar tissue—a healthy mistrust of Linux distros' ability to deal with "non-standard" file systems, when it comes to the root filesystem)

I've just gone through the process of configuring a new MBP with nix-darwin and home-manager, and I'm sold. Keeping my MacOS and my NixOS environments in sync has been a nice bonus.

I still run Homebrew for a couple of services and casks, but I'm down to less than 20 packages still installed that way.

There have been a few points of friction (which I'm used to as a polyglot with lots of active projects), but the community has been very helpful with ironing those out.

You can also run nixos-rebuild targeting your NixOS machine from your Mac which is a neat trick - and it’s how I update my home server.
Nix-Darwin is great! I wish the Nix installer on macOS were (a) always multi-user and (b) came with Nix-Darwin, so it could be a more NixOS-like experience out of the box.
When I choose tools I like to ask "Who has the hardest version of this problem? What are they using?"

I'm reaching the tipping point to adopt Nix, after seeing Nix as an alternative for supporting project after project. The unstated subtext always seems to be "Nix is what the smart kids are using, but it's harder to learn."

Haskell? Same religion. But the joke is that one needs a PhD in category theory to use Haskell at all, and package management has long been a Haskell sore point, yet Nix hasn't taken over.

The Lean Theorem Prover?

https://leanprover.github.io/lean4/doc/make/nix.html

A century ago, Hilbert's program to formalize and automate mathematics was stopped in its tracks by developments in logic such as Gödel's incompleteness theorems. There is a new push involving many leading mathematicians, using the Lean theorem prover. While some imagine computers replacing people, a better model is how a chess grandmaster checks their analysis using computers. Even as the experience of observing computer Go games leads to moments of amazement, as if observing an alien tournament, the role of a human to appreciate and generalize is preserved. Primates have long used tools; our future is to coevolve with machines.

Dependency hell and Gödel's incompleteness are cut of the same fabric. This is where I first read about Nix flakes.

I had R working with Nix on my work Macbook, but this was on a version of Nixpkgs from several months ago. Of course, one of the upsides with Nix is that I can look up the exact version of Nixpkgs that was working for me because it's in a git repo with the rest of my dotfiles :).
Thanks for the summary, it is very helpful! I love Haskell and its philosophy and I'm intrigued to find that there can be some of it in a package manager as well.

One question: How do you properly install things like R on the M1 Macs, then? Do you use a 'backup' package manager?

sorry OP by this is a clickbait rant from someone who just did not made his homework and ended loosing time and data.

- Homebrew is rolling - always was and never claimed otherwise.

- OTOH for key packages (say databases) it has available versioned bottles. for postgresql one have:

  - postgresql@10
  - postgresql@12
  - postgresql@9.4
  - postgresql@9.6
  - postgresql (points to latest) 
  - postgresql@11
  - postgresql@13
  - postgresql@9.5
- Finally, no one is forced to update everything at all. run `brew outdated` and pick whatever you want updated then `brew update foo`...

In short, none of what happened to the OP is due to inherent flaws in homebrew... QED.

(comment deleted)
brew will auto update on install by default.

why are you being this hostile while being completely wrong?

they aren't wrong, actually.
For databases specifically, I like a little tool called DBngin. It's perfect on MacOS for installing various versions of databases. I used to install MySQL 5.7 for an older legacy application because I was finding it challenging to juggle different versions on MySQL w/ Homebrew. I know it handles MySQL, PostgreSQL, and Redis. Maybe is handles other stuff, but I haven't checked.

https://dbngin.com/

Why did you want to `brew install virtualenv`? That’s no longer the current way to work with python. Virtual environments are now in the standard library:

  python -m venv /my/directory
I’ve never had any problem with homebrew in over a decade’s usage. But yes, don’t use it for python development tooling: use pyenv and python -m venv and pip for that.
I can't recommend pyenv and pipx enough. I use brew to install pyenv and pipx, and there ends my interaction with brew and python.

Pyenv builds all of my python versions. Pipx installs cli tools in their own env.

Precommit is also great for much more than just pre-commit hooks. It can install tools used for hooks in their own cache, no need to manage venvs yourself.

Pyenv will setup Python environments under your user and replace the system Python executable with a shim. Depending on your setup, it can create a lot of confusion (I have fixed a lot of colleague machines in the past year that were broken in one way or another).

Doing a `python[V.v] -m venv …` and then sourcing `activate` is conceptually much simpler and doesn’t affect any other terminal sessions you may have open.

Me 11 minutes from now: "why did you use venv? They replaced that 11 minutes ago with ..."
No. If you’re not an experienced python programmer then I can see that your comment might seem like a witty contribution. But I was actually providing good advice.
If you're not an experienced /anything/ then I can see how that comment might have seemed like a personal attack, but I was actually only providing an observation, from someone who's been around longer than "11 minutes", about python and the rate at which it and other similar entire systems and their library of best practices changes, dickface.
Absolutely. Brew manages pyenv, pyenv manages Python versions, venv manages Python packages / projects. Has been very reliable for the last decade or so, with my only complaint being the need for special linker flags when installing a new Python (homebrew openssl path etc), esp if doing an `--enable-optimizations` build (which I definitely recommend in the long run).

brew install pyenv pyenv install 3.9.7 cd ~/myproject pyenv local 3.9.7 python3.9 -m venv --upgrade-deps .venv source ./.venv/bin/activate

You're off to the races. (I think I got that --upgrade-deps flag right.)

nix.

It's confusing, but we'll get there. You'll need/want:

- nix, the tool/build system.

- nixpkgs, the world's most up-to-date and underfunded package repository.

- nix-darwin, bringing a NixOS experience to Darwin. Not perfect, but pretty damn great.

And optionally,

- home-manager, a nix-based opinionated tool to manage dotfiles and other stuff in your home directory.

And finally, some things to avoid and experimental features to use:

- do not ever use `nix env -i` to install things ala homebrew, apt, etc. This is a trap. You don't want this.

- use nix flakes. Sure, it's experimental, but it's what you _do_ want. Reproducible, version-pinned builds.

- if you use direnv, or are familiar with it, check out nix-direnv, which is like direnv on crack. Instead of managing your packages globally, manage them per workspace or project.

So you're saying use nix flakes instead of `nix env -i`?

I've been using `nix env -i` without any issues till now, but I'll explore nix flakes.

I disagree with "don't use nix-env --install; use <much harder thing> instead".

I see "nix-env --install" as a gateway drug to using Nix. It's effortless, and already easy to see benefits from using Nix (like you can easily get the same set of packages on different OSs).

Rather, it's worth explaining why it's bad to use. The footgun I ran into was that I'd caused a messy state by installing something and forgetting I'd installed it.

Maybe nix flakes and home-manager and nix-darwin are really cool.. but they're also much harder to use, and surely overwhelming for someone who just wants a way to install packages. I think it's like telling someone to learn Kubernetes when they're wondering how to serve the website they wrote. -- I think it's easier to appreciate these once you've gotten your feet wet with nix.

You never want `nix-env --install` without it being `nix-env --install --attr`, though, because `nix-env -i` is like a billion times slower than `nix-env -iA`, and that gives people a really bad first impression.

But yeah I agree, it's fine to use `nix-env -iA <package>` or whatever. It's fine when you're getting started, and it's fine for a slightly more persistent way of trying things out than `nix-shell`.

> Rather, it's worth explaining why it's bad to use.

My biggest problem is that it's not version-controlled. I don't use home-manager, and (still) haven't looked into Nix flakes.

Instead, I put `export PATH="/path/to/my/repo/result/bin:$PATH"` in my ~/.bashrc, and inside that repo I have a default.nix file:

    buildEnv {
      name  = "my-packages";
      paths = [ foo bar baz ... ];
    }
Running `nix-build` will update the result/bin symlink to point at the new applications.
Nix with nix-direnv is awesome!
I've never used nix, but it sounds interesting. What getting started guide would you recommend? Ideally one that has all these "insider tips" that you offer, so that I learn to use Nix "properly".
A while ago there was a post on HN about pkgsrc[1][2][3], which works on Mac, among other platforms. I haven't tried it, but it may be worth a shot.

[1]: <https://rubenerd.com/using-netbsds-pkgsrc-everywhere-i-can/>

[2]: <https://news.ycombinator.com/item?id=27293108>

[3]: <http://www.pkgsrc.org/>

I checked and it appears to suffer from the same problem as MacPorts in only making the ancient version of awscli available: http://cdn.netbsd.org/pub/pkgsrc/current/pkgsrc/net/py-awscl...

I wasn't able to immediately find any issue tracker for pkgsrc packages, and it seems they're a "mailing list and IRC" type setup, which if true means it definitely isn't for me

why does the protocol by which bugs and problems get tracked matter, its not like you dont have an email address already... the bug reporting tool is mentioned on the packages page but not the most clear. http://www.pkgsrc.org/#index2h1
I did qualify "for me," indicating that system is not the way that I want to interact with a project

The answer to your question is that searching years of email threads is not the same UX as navigating to a dedicated page for managing the lifecycle of a (bug|feature) that tracks when I can expect a new, or working, version of -- in this case awscli-v2 -- to show up, or (if reasonable) that I can indicate to others that I'm willing to take responsibility for doing the work to package it, in order to avoid duplicated effort

Plus, again for me, I don't need more email traffic in my life

I understand for you, and i understand the UX is different but i dont see how github issues are much better, compared to something like lists.sr.ht or lkml. I find github issues are just as disorganized in a lot of projects with lots of closed due to duplicate and etc. guix has a bug tracker backed on email that has the ux i think you might expect, i find at least, it worked (while i contributed to it) just as well as a non email workflow.

Anyway I didnt really consider that this is a personal thing so fair enough to not want to deal with the different problems.

i agree that most people don't want to bother with mailing lists and/or IRC these days, though there are a couple of alternative options

https://www.perkin.org.uk/pages/pkgsrc-binary-packages-for-o...

https://github.com/joyent/pkgsrc

https://www.netbsd.org/cgi-bin/sendpr.cgi?gndb=netbsd

https://pkgsrc.se/net/py-awscli

It appears those links made the same assumption as did @alnja8a in the sibling comment: my concern is not, at this moment, bugs in pkgsrc itself rather my concern is with tracking who is working on fixing (in our example at hand) awscli-v2

Now, maybe if I go trawling through mailing lists or (shudder) IRC I can find out what the status is, but that's beyond my level of energy expenditure for some niche packaging system

I started using nix. It’s difficult and search results are not often helpful.
Your honesty is refreshing.

I've seen countless people trying a new technology/tool, and overselling it as 'amazing' and super easy.

Seeing a post like yours helps to keep the discussion grounded in reality, with tools that looks nice on paper but have practical downsides as well.

I agree with this general sentiment, but I'll add that it's worth reading most posts about Nix through this lens.

Finding your sea legs is rough, and IME people who completely deny this are few and far between. The reward is a pretty impressive lever.

The thing I use and like most in nix is nix-shell.

I set up a shell.nix file on my projects, and together with direnv the environment switches with the right dependencies for each project.

Shameless plug, I wrote about this recently on medium: https://link.medium.com/cYkKMtdHRkb

Nix IS amazing. It is NOT super easy.

Parts of it are getting easier, and it has an exceptionally smart and helpful community. But it's not smooth and pretty and easy to pick up like Homebrew is. (And that does suck)

Nox is much easier interface to nix. I often use that instead of nix-env.
(comment deleted)
Fight through it for another couple of weekends - the Stockholm syndrome feels sooo gooooood!

I found it much more helpful to find people's own Nix setups and learn from them, by the way. Mine is at https://github.com/Smaug123/nix-dotfiles - like all such things, it's a WIP, and I'm definitely still a noob, but bits of it may be able to help.

After years of dealing with it I just run most of the software from docker containers and use homebrew for random cli tools.
This was also going to be my comment, homebrew for cli tools and casks for some gui apps, all other environments in docker containers.
Ditto. Anything mission critical runs in Docker via Docker-compose, so I can manage every aspect.

And for any cli tool that's also mission-critical, it can be run within Docker so I can pin it or keep it bleeding edge more easily.

For the important stuff, performance and ease of installation can take a side seat to stability.

Homebrew needs to do a better job of communicating that you shouldn't use it for project dependencies, because every time there's a Brew thread on here, a bunch of people come out complaining about this kind of thing. "Homebrew broke my build by updating PostgreSQL and Redis". They shouldn't need to communicate that, but clearly, they do.

Use Docker, probably. Homebrew is for your tools, not your dependencies. Is the system you're deploying to a Mac with Homebrew? Do all your collaborators use Macs with Homebrew? If the answer to either is no, why were you trying to use Homebrew for that in the first place, even if it were otherwise good for that? Would you use Homebrew to install Node modules for your project? Python packages? No? When why are you letting it define which version of PostgreSQL this project depends on?

Genuinely, is this attested as the project philosophy anywhere?

Because right now https://brew.sh leads with "The Missing Package Manager for macOS", which would lead anyone to think it does the same as a package manager for Linux, and they're _full_ of developer dependency packages.

The thing is, you also shouldn't be using apt or whatever for managing project dependencies, unless you and all your fellow devs match Prod exactly, both with distro and exact versions of everything. People do it anyway, but it's bad practice for exactly the same reason that using Brew for it is bad practice, and it's barely easier than doing things right (and, very early in the life of a project, it'll become less easy than doing it right).

It's not about project philosophy, it's about using the right tool for the job. Now, since people keep running into this problem, maybe they ought to put a warning about that right up top in a big banner on the site, I dunno, but it's not specific to Homebrew.

Imo you shouldn't use a typical Linux distro package manager for project dependencies either, unless you're only ever gonna deploy every app you're developing on that machine to the same version of the same distro.

This is not because there's anything really wrong with them for what they're designed to do, but they install packages globally, and different projects may want different versions of the same thing.

If your only problem is you don't like it surprise-updating everything, maybe you should set up an automated patching schedule.
This si literally why docker exists. I would never install something on a system and then complain it is being updated from time to time. The system needs to stay safe and follow a path of updates in order to cover vulnerabilities and such. Put it in docker and version lock it.
Docker performs pretty poorly on macOS.
If you want package managers, go Linux.
I have reasonable experience with macport, just remember to enable multithreading, or it can be exraordinarily slow.
I very much dislike that autoupdate is the default. This is user-hostile.

I instructed you, brew to install something. Not to spend an eternity autoupdating things.

I've personally had very good experiences switching back from Homebrew to MacPorts. Wouldn't go back to Homebrew.

I find it much faster now, which is quite funny to me because back when Homebrew was new (and a lot less opinionated) it was much faster than MacPorts, especially with the bottles (binary packages) feature.

Today, MacPorts has binary packages, doesn't randomly force incredibly slow updates when I just want to quickly install something or run a package search, has entirely opt-in telemetry through installing a package (mpstats) and still lets me customise packages (through the variants system, which is more powerful than the with --with-feature system Homebrew seems to have abandoned).

The only pain point I've found is upgrading to new macOS releases, though I've often found just reinstalling MacPorts itself will get me going again in a pinch without having to take inventory of my installed ports and reinstall everything from scratch.

> I've personally had very good experiences switching back from Homebrew to MacPorts. Wouldn't go back to Homebrew.

I have been much happier with Macports than with Homebrew (which I try every other year to see if it’s improved).

> The only pain point I've found is upgrading to new macOS releases, though I've often found just reinstalling MacPorts itself will get me going again in a pinch without having to take inventory of my installed ports and reinstall everything from scratch.

I used to use the commands suggested on the Macports website (save the list of installed packages to a file; update OS; install Macports; re-install ports). But since a couple of upgrades I have decided to use this as an opportunity to get rid of ports I don’t actually need.

I also switched back after one too many issues with brew file ownership and permissions.
Macports made my life hard three times I upgraded OSes from having to migrate Macports versions, just leaving broken files in /usr/local/*. The worst instance was Mavericks, when it suddenly said i had no ports, after 10 years on the same image. It did something similar during the Monterey update. I'm now 100% brew but still have broken artefacts from MacPorts littering my system. I'm also still using the same image from 2012, moved to new machines with TimeMachine, so that could be it, but I'm damned stubborn.
Perhaps it would be great opportunity for you to clean install macOS to start anew and start fresh from there without worrying about lingering old files in the system.
I know, I know.

I tried to do a clean install on my 2012 MBP to get a feel for what would break. Unfortunately the 2012 is out of service and Big Sur kept powering down randomly. It runs Ubuntu 20.04 just fine tho.

I think OSes shouldn't atrophy. So I'm super-testing TimeMachine.

Homebrew packages break on major macOS upgrades, too. It's not up to the package managers what Apple does or doesn't rip out on a given release
> At this point I should know better than to install postgres via homebrew.

No. At this point you should know better and read the documentation. Whatever you switch to next, you are going to have similar issues and surprises.

I've had big Postgres issues with Homebrew. I've never had "similar issues and surprises" with Postgres.app.
Postgres.app is not a package manager.

If you pin Postgres in brew, not installing `postgres` but instead `postgres@11.3` instead, then you won't have any auto upgrade issues. You can then upgrade on your own schedule. Brew will keep Postgres at your selected version.