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.
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.
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.
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).
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.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 :)
That's actually over-complicated, since I used to use nix-darwin and haven't bothered to un-pick it yet.
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.
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 :)
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.
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.
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.
One question: How do you properly install things like R on the M1 Macs, then? Do you use a 'backup' package manager?
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.
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)
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.
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?
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)
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.
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)
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 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.
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.
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.