Published on

Nix on MacOS - The Good, the Bad and the Ugly

Introduction

In general, using Nix on macOS is rather pleasant. Nix-darwin, however, is not as satisfactory. As the article's title implies, we begin with the "Good." Then comes the "Bad", which I define as issues that Nix and Nix-darwin developers can control but have not yet addressed adequately. Finally, we discuss the "Ugly"—issues that lie solely within Apple's control and are therefore subject to their benevolence, or lack thereof.

The Good

Now for the good parts. Nix simply works, thanks in part to Determinate Systems' work on their Nix installer. Nix development environments have proven invaluable for the engineers on my team, especially when managing multiple versions of a language or framework. This dependency management mess would be a real challenge to solve with traditional package managers. Put simply - brew sucks. Everything else sucks. Nix replaces them all. With Nix, it's just a matter of nix profile install nixpkgs#app-of-some-specific-version. It does not require further tweaking and integrates nicely with the rest of the environment already provided by macOS. This concludes the "Good."

The Bad

Nix-darwin is far from perfect. Many configurations that can be performed via the Settings app or in the terminal with commands like defaults write <com.option.name> are not exposed in the Nix-darwin Module System. Hopefully, this will improve as Nix-darwin evolves.

A lot of stuff is simply broken. For example, Karabiner Elements barely works as a packaged option. When installed without Nix, Karabiner works as it should.

Sometimes things randomly disappear. Applications do not show up in the launcher menu. Applications may work or stop working randomly. I use an application called "Autoraise," which provides the essential "focus follows mouse" functionality (thanks, Apple?). There is a flake packaged by a volunteer, which used to work but now does not. Why?

Firefox is marked as badPlatforms because it won't compile. However, there is a Firefox in Home Manager packaged as a .dmg file. If you use this one, you're in for a ride. The situation can become worse if you have Firefox installed the usual way alongside the Nix-managed one - good luck setting the separation boundaries! I believe there is also an overlay providing Firefox that does compile on MacOS, but I could not recall it.

I've heard some good things about people bringing their old Macs to life with the help of Nix, but I am not sure Nix and Nix-darwin are extensively tested on older (or even the latest minus one) MacOS versions. I have a corporate MacBook with Ventura and a personal one with Sonoma, and Nix encounters some bugs on Ventura that are not present on Sonoma. Or maybe that's the ugly part?..

Regarding deployment tooling, I should mention Deploy-rs. I use it to provision multiple Linux hosts; however, for whatever reason, it does not work for me on MacOS. I could not make it work with either Mac to Mac or Linux to Mac, including remote builders. I am not sure if I am doing something wrong here, but I also suspect that the corporate laptop being locked down to a degree plays a role. I would be glad to hear about your experience and to learn how to streamline all of this.

The Ugly

And here comes the Ugly: it's hard to deny that Apple, being a tech giant, is one of the most user-hostile corporations ever founded - simply because they can afford to be user-hostile. The entire Apple ecosystem is designed to lock you into a walled garden, forming habits they claim are "different," making it hard to switch. The closed-source nature of their APIs makes it difficult for third-party developers to extend MacOS. Apple simply does not care about these developers. As long as Apple's part of the tech duopoly is upheld and developers continue to pay hefty fees to address Apple's user hostility, one issue at a time, Apple remains indifferent.

This culture manifests itself in various ways, surfacing all the ugly pain points.

Despite all the work already done by Nix developers and Determinate Systems, MacOS still occasionally deletes files - maybe not the entire Nix store, but it's a permanent arms race between Apple and Nix developers.

Nix-darwin also has to constantly fight against MacOS to persist settings that Apple likes to toggle back and forth at will.

Some aspects of Nix-darwin must follow implicit conventions. For example, the hostname you specify in your Darwin configuration must match the already assigned hostname of your Mac. You don't "assign" a hostname - you "pin" it. Changing the hostname in your configuration won't have any positive effect and may even cause you trouble.

Permissions make everything harder to manage. Returning to Karabiner Elements: adding it as a module and then rebuilding the system will trigger scarejump prompts to allow it to snoop on your keyboard via the accessibility API. You have to toggle such things in one swift maneuver, or you may find part of your system in an invalid intermediate state. The system is fragile. Rollbacks for such things are virtually non-existent.

All these supposedly minor issues snowball into a huge UX friction. It culminates in the inversion of the control flow - not "Nix over Mac," but "Mac over Nix." You're not the owner of your laptop. Apple is.

Closing Thoughts

In the end, I don't think Nix is the solution to MacOS declarative management - more of a remedy. The relatively small "good" pales in comparison to the larger "bad" and "ugly." To paraphrase Churchill, "...Nix is the worst package manager on MacOS except for all the other package managers that have been tried from time to time." Unless Apple opens up MacOS (unlikely) or the EU legislates extensively against them (slightly less unlikely), I do not see the situation diverging from the status quo anytime soon.

I will really appreciate, if you subscribe to my newsletter.
You inspire me to keep writing. Every reader counts.
You will receive email with link to confirm the subscription.