Hacker Read top | best | new | newcomments | leaders | about | bookmarklet login

I try it every few months because I _really_ want it to work locally. Nix itself works pretty well, and most of the packages work well, but there's just enough brokenness in important utilities to keep me going back to brew for now.

It's certainly possible to mix them, and use nix for most things with brew as a crutch until nix packages get better, but I already have the App Store, stack, cargo, pip, gem, and npm trying to manage packages on my system, and I really don't want to add a brew replacement until it can be a complete replacement.



sort by: page size:

I've used it as my primary package manager on macOS for six months, but ended up dropping it. My main reasons -

* Nix doesn't have support for GUI apps like homebrew cask does - which meant I couldn't drop homebrew anyway. * The nix ecosystem forums suggest using nix-shell for managing packages for other languages, eg. python, java - but it's been really difficult to convince team members to use nix instead of pyenv, conda, gradle etc


You very clearly articulated a huge pain point with brew.

I've been ruminating on making the switch to nix, you might already be familiar with it, but if not, here's an article I came across:

https://wickedchicken.github.io/post/macos-nix-setup/

Reproducible builds are super appealing: "Nix builds packages in isolation from each other. This ensures that they are reproducible and don't have undeclared dependencies, so if a package works on one machine, it will also work on another."

As is the focus on reliability: "Nix ensures that installing or upgrading one package cannot break other packages. It allows you to roll back to previous versions, and ensures that no package is in an inconsistent state during an upgrade."

From https://nixos.org


Brew is fine for what it is. Nix generally shines by being a way more general solution to the problem, which means you can take the nix managed version of things and move them across machines/OSes very easily.

The main advantage of nix against brew purely as a mac package manager is the ability to easily use versions of things that aren't HEAD (or to use multiple different versions of things for different reasons). Homebrew has a really clunky way to do that, but its much more straightforward in nix.


I've switched from brew recently.

It (Nix) provides a much more pleasant experience on Linux/NixOS itself.

On OS X, like right now, after switching to El Capitan, you begin to see the disadvantages.

In fact any major change in some packages, require a lot of digging around and most of the time, the solutions are not at all obvious, and mostly undocumented properly.

Also, when you do find a workaround, you will still have to compromise and compile everything from source, waiting for the binary cache (hosted by the project) to catch-up.

The flexibility, and cross-platform nature of Nix, is something that's difficult to resist though (regardless of the philosophy of the project).


Not the person you're asking, but I use nix on my MacBook and ditched brew after a few weeks. The main draw for me was that I was already using home-manager on NixOS, and being able to share the same config on macOS was pretty compelling. I had to sprinkle a couple conditionals in the home-manager config to account for things that are linux-only, but it was pretty painless.

Here's an example of using `pkgs.stdenv.isLinux` to conditionally install stuff (there's also an `isDarwin`, if you prefer): https://github.com/yusefnapora/nixos-system-flake/blob/660dd...

For my own use case, I install a few things "globally" in my home-manager config (neovim, vscode, fish shell, etc.). Then each of my projects gets its own flake with a devShell, and I use nix-direnv to bring things into the PATH when I cd into the project directory. I also use `nix shell` a fair bit if I just want to run something in a one-off shell session.

You can also use nix profiles if you're looking for a more brew-like experience, but I never really mess with those. I figure if I want something to be persistently installed, it's better to just stuff it into my home-manager config so it will be there on all my machines.

On the whole, I much prefer nix to brew. I'd still recommend brew to people that don't want to bother with learning nix, but if you're already running NixOS I'd say go for it.


The default.nix thing is nothing like what home-brew has. Not really kidding here, nix is like git is to svn. Very different in philosophy.

I can setup scripts that install and configure things for emacs to make sure it always runs in an environment that has all it needs. But with the benefit of not having to have everything installed globally.

I can have multiple versions of whatever installed into /nix at once. But still not have to worry about breaking things that need both versions.

As for package availability, I've not hit any issues. It has most of what I personally need.

What I hit more often is random breakage or having to update derivations that only ever got created or maintained from a linux perspective.

I'd say its in the "developer not afraid to fix broken build problems" category as a package manager. Its not bad, but it is really annoying when you have to revert back to a prior generation because some package you use got updated and now won't build because of its test suite failing.

Random stuff like that happens a few times a month, nothing huge though honestly.


Here's why I don't like Homebrew, and why I believe Nix is (almost) strictly an improvement over it:

1. Updating packages is not safe. If I update openssl and the ABI changes, all of my currently installed packages that depend on it are now broken -- time to rebuild everything. I've burned way too many hours on ABI breakage and rebuilding everything. That problem can't happen with Nix because Nix will ensure that each library is linked precisely to the versions of the libs they need.

2. Nix has a continuous integration server (called Hydra[1]) that builds every package, and caches the binaries. Because Nix knows each packages entire dependency graph, Hydra only needs to build just the packages that have changed. When I want to update some packages, I can count on not having to rebuild everything myself. Each binary package is signed, so I know my stuff is coming from the build server, regardless of whether or not I get the files through a cache or third party. I can also run my own Hydra instance to build my OS X and Linux packages, and I can share the binaries with others should I wish.

3. The lack of determinism. With Nix on OS X, packages are built using OS X's native Sandbox APIs to ensure that the build process can only see the dependencies that were explicitly specified. This guarantees that if the build works on my machine, it will work on yours -- whereas I've seen brew formulas under-specify configure flags and such, resulting in the default of linking to non brew installed libraries, causing quite a bit of confusion when things don't work at run time, or just flat out fail to build.

4. Brew is OS X specific. Nix works on OS X, Linux, and a FreeBSD. As someone who deploys to Linux virtual servers, it's nice that I can use the same versions of packages both in development and production.

It's not all roses, though. We have a smaller community of OS X users at this point, so not everything works (thus my "almost" qualification). Regarding the underlying tech and the outlook for the future, Nix is a superior tool.


Yeah, I switched completely to nix after being frustrated with homebrew constantly breaking things (any time I installed something. (Usually involving libicu being replaced with a different version.) And then had to pick up homebrew again for a couple of things.

I _really_ like being able to drop into a shell with a few additional packages installed. But nix does have a learning curve and some rough edges. I found it tricky to use things like libraries outside of nix's build process. And there is a bit of an impedance mismatch when trying to use languages that have their own package management.

So I've got nix for a bunch of software, a couple of libraries in homebrew, and native package management for various languages (cargo, ghcup, lake, idris).

I also reluctantly installed agda via homebrew because I can't get it to build. (Haskell mostly works on M1).


I switched from brew to Nix about a year ago. Nix is, like many powerful tools, difficult to learn, but rewards the effort down the line.

Nix is best thought of as a way of building software, not simply as a package manager, though you can use it only for that if you want (and that is probably the best way to become acquainted with it). So while you can certainly use Nix instead of brew, that is just scratching the surface of what Nix can do for you, if you are in the business of software development or devops. In my view, that is the primary reason to make the switch, because Nix is so much more than just a package manager.

Among the benefits of Nix are:

* Reproducible builds - If you and I use the same Nix expression to build something, each on a different machine, you can be sure that you and I will each produce the same build artifacts (binary executable, library, docs, etc.). [Note - on Macs this is occasionally not true due to "impurities" that creep in from the base OS, but the Nix folks are working to make this a thing of the past on Macs, as well -- see "sandboxed" builds.]

* Distributed builds - Let's say I have a laptop and a desktop. I can configure my laptop to use my desktop as a remote builder for faster builds. This even works for building, say, Linux packages from a Mac. Just tell Nix on your Mac about any Linux hosts where you are also running Nix, and if you ask the Mac to build a Linux package, it will farm the work out to the Linux remote builders.

* "Channels" - You can choose from one of several Nix "channels," where a channel is a subset of the full Nix package set. Some channels are pinned to a specific official release -- 17.03, 17.09, etc. Think of these like you think of Debian or Ubuntu releases. These receive only minor backported version upgrades and security fixes. If you want something more up-to-date, you can run one of the "unstable" channels. These are updated more frequently and may break from time to time; however, the continuous integration server (see below) can give you some guarantees, namely that the packages in these channels will at least build correctly. The unstable channels are equivalent to what some Linux distributions call "rolling releases." (And, if you want, you can just build against the git repo and control your package versions that way, eschewing channels altogether.)

* A community package cache - one of the advantages of reproducible builds is that build artifacts can be cached and used by everyone. The Nix project runs a continuous integration server that builds packages for x86_64, i686, aarch64, and macOS. As long as stay on one of the channels (see above), there is a good chance that your package will already have been built by the CI server, so that your machine can just download the end product and doesn't have to build it. (If you are a Haskell developer like me, this can be a godsend! The CI server builds a pretty reasonable subset of Hackage.)

* Easy package overrides and additions - this and the excellent Haskell support were the main reasons I originally switched from brew to Nix. Perhaps brew has a better story for this in 2018, but overriding packages and adding new ones to the brew package set was not particularly easy when I used it. In my time, it usually involved maintaining your own brew fork in Git. With Nix, it's a simple matter of importing an "overlay" into your Nix configuration. The overlay can modify existing packages, or add whole new ones, with just a few lines of configuration and a Nix expression (equivalent to a brew "recipe," or whatever they call it). Also, I can easily share my overlays with others; just publish it on GitHub and tell someone to import a single file from that repo into their Nix config, and they will see the same package overlays as I do. Finally, overlays are composable by design, so you can combine them from multiple sources to create a single package set tailored to your needs.

I could go on, but I'll stop there. Oh, except to mention that cross-compiling support is coming very soon, so that you will be able to build packages for, say, armv7l-linux on your very fast x86_64-linux build server. If you do embedded development like I do, this is huge. When this work is finished, I believe that only Debian/Ubuntu will have a similarly compelling cross-compiling story (minus all the other benefits that Nix brings, of course).

Interestingly, though my initial motivation for the switch from brew to Nix was to use it as a package manager, one year on that is easily the least of the benefits I've derived from learning it. It has completely changed the way I build and deploy software and Linux hosts. (I have not mentioned here NixOps, because it is not relevant to Macs, but if you do any kind of Linux deployments and you are using Nix, you will probably want to at least take a look at NixOps.)

Anyway, highly recommended.


If you are only using nix as an imperative package manager just like homebrew, there is little advantage.

One area where nix shines is that you can write nix code to build a reproducible dev environment for your project.

You can think of it kind of like if you could use a Brewfile to build a virtualenv that doesn't touch your system at all.

I like this a lot because it makes dusting off old projects way easier. I don't have to worry about the state of my system, or reverting to an old version of ruby, etc. to get the old project running again.

Nix is also much more powerful than a Brewfile. You can override the versions of dependencies or even package your own custom dependencies and use those in exactly the same way. The learning curve is steep, but once you learn you have an incredible amount of flexibility and power all built on a robust foundation.


Nix aims to solve a much more general problem than homebrew. If all you want is to get some packages on your system, there might not be that much in Nix compared to brew for you. The zen of Nix is that building packages is expressed as pure functions, where inputs, outputs, and side-effects are carefully managed. Thus, if you have specific build, packaging, or environment configuration to do, nix can be really helpful. Since everything is in code and every generated nix configuration is effectively isolated from the rest, it makes rolling back to previous configurations trivial in the event something goes wrong. That, and you can VC a config, and in general once a package is properly expressed in Nix it more or less solves the "works on my machine" problem

Maybe try out Nix while you're at it, too! I'm using NixOS, and I'm pretty happy with it so far. The standalone package manager fills the same niche as Homebrew, I think.

Even better for getting started: Using nix as an additional package manager that won't fight with whatever pre-existing OS uses. My first exposure was using nix instead of homebrew on OSX.

Why leave out nix? It's been a good alternative that works similarly on Linux too for unified environment.

I hate Linuxbrew when it tries to install stuff in a weird place that is /home/linuxbrew/.linuxbrew/ and as soon as you try to change the installation path, half of your packages starts compiling and since it's not the major way to do things, it often breaks and can't even compile.

I don't like scaring other users on the same server creating stuff at some bizarre location.

No idea how they didn't just settle in /use/local/ as it does on Mac or just use /opt/brew/ like a sane choice would be.


Some unsolicited, anecdotal advice I hope will be appreciated -

After several years of perennial macOS environment hell (part of which was spent working in a much more research-oriented environment - e.g. lots of ancient HPC packages, etc.), I made the jump to just using Nix on macOS [0]. Takes a little bit of learning (realistically just a couple hours to get productive IME - just enough to get acquainted with nix-shell [1] and build some configs). After a few months, I had the thought to look at what I still used brew for and realized I could just move to Nix completely - and remove Brew. I back up all my nix configs to a git repo, just in case - and whenever I switch to a new machine, or "brick" my current one - I just reinstall nix, pull in my configs, and I'm good to go - takes 5 minutes (a conservative estimate tbh). The only caveat is to just check the community [2] before upgrading to the next macOS version to make sure any issues have been ironed out. In the early days of macOS support, it was a bit finnicky between updates - I haven't had any issues for the last couple years that weren't my fault (for example, booting into recovery mode and accidentally deleting the nix store APFS volume - even then, all I had to do was reinstall nix and pull my configs).

It is so nice to just "declare" I want to use and just...use it. Want to try out ripgrep for something? `nix-shell -p ripgrep` Not what you want? just exit the shell. Too much unused crap taking up space in your Nix store? `nix-collect-garbage`.

There's even darwin-nix [3] as a sort-of "nixos-for-macos" - I started using it recently, mostly for managing macOS settings declaratively, and it's great - but honestly 99% of the usefulness I get on macOS from Nix is just using the package manager!

[0] https://nixos.org/download#nix-install-macos [1] https://nix.dev/tutorials/first-steps/declarative-shell [2] https://nixos.org/community/ [3] https://github.com/LnL7/nix-darwin


I've used Nix with Nix-Darwin on my macOS machines for a couple years now. The primary benefit is that when I get a new macOS machine, it's only three steps to having ALL my apps, configurations, etc. exactly as they were before:

1. Download Nix installer (I prefer the one by Determinate Systems)

2. Clone my Nix configs (public, so I don't even need secrets like keys yet)

3. Run `make`

I then wait around 15 minutes or so (mostly network time) and I'm good to go.

ONE BIG RECOMMENDATION: I don't like using nix-darwin to manage graphical apps directly. It's a bit awkward. But, you can use nix-darwin to declaratively manage `homebrew`, so I still get my graphical apps from Homebrew. The linked article seems to suggest ditching homebrew entirely but I found its best as a mix of both worlds with Nix being the source of truth to manage everything else, including brew.

You can find my configurations on GitHub but note that if you're new to Nix you would do better finding a simpler starting point: https://github.com/mitchellh/nixos-config (these are shared Nix configurations between macOS, Linux, and WSL on Windows).


Nix was the only thing holding my sanity together when I was using Mac last. Maybe it was just the Apple Silicon transition, but Homebrew did not have parity with it's x86 version which led to wildly complicated scripts just to get dev environments arranged similarly. Not the sort of thing you want to deal with regularly.

I recommend giving it a whirl if you're at your wit's end with Mac packaging: https://nixos.org/download.html#nix-install-macos


Well, you don't have to use NixOS, you can just use NixPkgs either as a way to familiarize yourself or to manage a project--personally, I'm hoping after a few things get fixed I can replace Homebrew with it.

Even though containers have had a lot of buzz and tooling built around them in the past few years, it's good to see how other approaches can solve similar problems with different pros and cons.


Nix (specifically nix package manager on MacOS) sits in a weird spot where it is absolutely indispensable for me personally but I am absolutely hesitant to recommend it to others without extreme caveats. I really wish the UX of it were much better, which ideally then would lead to higher adoption and less frequent 'osx-isms'.
next

Legal | privacy