DEV Community

Yufan Lou
Yufan Lou

Posted on

8

Use Nix on macOS as A Homebrew User

Documenting my efforts following Salar Rahmanian's Moving from Homebrew to Nix Package Manager.

First of course is to install nix-darwin:

nix-build https://github.com/LnL7/nix-darwin/archive/master.tar.gz -A installer
./result/bin/darwin-installer

Some interesting lines from the log:

Would you like edit the default configuration.nix before starting? [y/n] n

I haven't used nix outside of building Haskell libraries with their configuration, so I don't know anything about configuration at this point. Default it is.

warning: Nix search path entry '/nix/var/nix/profiles/per-user/root/channels' does not exist, ignoring

This line appears in multiple locations. It is apparently related to updating nix-darwin, like so:

nix-channel --update darwin
darwin-rebuild changelog

A nix channel is like a homebrew tap I suppose.

Would you like to load darwin configuration in /etc/bashrc? [y/n] y

Upon reading this line my first reaction was to look for zsh in the nix-darwin documentation because I have changed to use zsh following macOS Catalina default. Unfortunately I cannot find much else than a passing mention in the README. I don't know at this point if the installation will work on my machine.

Would you like to create /run? [y/n] y

What the heck even is /run? The documentation of Nix stuff so far has not a bit consideration for onboarding. This front-loading of unnecessary information is very frustrating, especially compared to the simple first steps of Homebrew.

After installation, there would remain a result symlink in the current directory where the installation command was run. Nix documentation has this much to say:

nix-build registers the ./result symlink as a garbage collection root, so unless and until you delete the ./result symlink, the output of the build will be safely kept on your system. You can use nix-build’s [-o](https://nixos.org/nix/manual/#opt-out-link) switch to give the symlink another name.

There should be a nix-run-once command which automatically runs the built binary, skipping this symlink altogether.

Now that I have the nix-darwin installed, I can start install packages. I have picked aria2 to install. It is a download manager which aims to use every bit of your bandwidth. The command for looking for aria2 is

nix-env -qaP aria2

(Sigh) -q as in --query, to say we want to search. -a as in --available, to say we want to search in all available packages, as opposed to --installed which is the default. -P as in --attr-path, as for some reason Nix calls package name "attribute".

The result of the query is

nixpkgs.aria  aria2-1.35.0

I guess I put the first part in my configuration file.

  environment.systemPackages =
    [ nixpkgs.aria
    ];

Now I just need to run

darwin-rebuild switch
zsh: command not found: darwin-rebuild

(╯°□°)╯︵ ┻━┻ Of course!

Searching for "zsh" in the repo yields two useful issues: issue #202 and issue #193.

Issue #202 mentions "user shell wasn't enabled in configuration.nix". I have noticed programs.zsh.enable in configuration.nix but I don't know how to apply it without darwin-rebuild. Then it occurred to me that I could simply run the installation again. Nix is supposed to be reproducible, right?

./result/bin/darwin-installer

And it worked, and as expected from issue #193, the installer does not overwrite existing etc files:

warning: not linking environment.etc."zprofile" because /etc/zprofile exists, skipping...
warning: not linking environment.etc."zshrc" because /etc/zshrc exists, skipping...

At this point I already have darwin-rebuild in PATH for some reason, but I decided to go all the way. Following issue #193, I move the original files to a .local postfix so the nix generated files would load them. I then run the installer again.

sudo mv /etc/zprofile /etc/zprofile.local
sudo mv /etc/zshrc /etc/zshrc.local
./result/bin/darwin-installer

And all seems well. Just to be sure I open another new terminal, and run

 darwin-rebuild switch

Yes, I can run it! Yet what greeted me was

error: undefined variable 'nixpkgs' at /Users/ditto/.nixpkgs/darwin-configuration.nix:7:7

(╯°□°)╯︵ ┻━┻ Are you kidding me?

Fine, looking at the example, I guess I just have to use pkgs instead of nixpkgs. Why doesn't the query display pkgs already?

darwin-rebuild switch

Finally, the rebuild worked, with aria2c correctly in PATH.

In total, this took me 4 hours. This is an unacceptable onboarding experience to me, and I am not recommending Nix to anyone.

I do not think I will replace Homebrew with Nix. I do like a file which I can use to rebuild my development environment. I think I will try Homebrew Bundle for that purpose. I will probably reserve Nix for development dependencies, and towards that I am looking at Nix + Bazel = fully reproducible, incremental builds.

Image of Datadog

Create and maintain end-to-end frontend tests

Learn best practices on creating frontend tests, testing on-premise apps, integrating tests into your CI/CD pipeline, and using Datadog’s testing tunnel.

Download The Guide

Top comments (0)

Image of Docusign

🛠️ Bring your solution into Docusign. Reach over 1.6M customers.

Docusign is now extensible. Overcome challenges with disconnected products and inaccessible data by bringing your solutions into Docusign and publishing to 1.6M customers in the App Center.

Learn more