Package management on macOS with Nix-Darwin

64 points by photonbucket 1 year ago | 31 comments
  • dlyons 1 year ago
    I’ve wrapped nix-darwin, home-manager etc in a Nix configuration for macOS, with a starter template and simple installer.

    I’ve been running it for a couple years, you can use it to try Nix without as much up front learning.

    Almost 1000 stars!

    https://github.com/dustinlyons/nixos-config

    Edit: Just crossed 1k! Thanks HN

    • davidpfarrell 1 year ago
      (this prolly deserves its own blog post somewhere)

      The most useful setup pattern I can share for both nix-darwin and home-manager is to configure them to store their rc files next to the system files, and not overwrite them ...

      This keeps darwin/hm from fully replacing your mac /etc/zsh* ~/.zsh* files on each update and also keeps os system updates from destroying your nix files ...

      You instead add sourcing statements in your system/home files to bring in your nix files.

      These sourcing statements are nuked after every OS upgrade so first time you login, nothing looks right in your shell.

      For this, I keep a copy of both the system file before the nix sources and a copy of the file after the nix sources ... If the post-updated version of the system file matches the backup then I can simply replace with the backup of the versions with sources included ... If they don't match, then I have to review the file, manually add the sources, and create new backups ...

      I'll also say that the system files haven't changed in a long time (zsh) so I can just copy my etc/zsh*-nix-backup files into place then restart my shell and be back to good ...

      • jordanreger 1 year ago
        Have you tried using the Determinate Systems installer? This (supposedly) helps to not break everything on system updates. As far as I can tell, it works.
        • pxc 1 year ago
          It adds a launchd service that makes sure stuff sourcing your Nix environment setup script is present in all your shell units on boot, so they get reestablished when macOS updates nuke them.

          macOS apps do weird shit to work around macOS quirks. But it's a really good installer. Can't recommend it enough.

    • IfOnlyYouKnew 1 year ago
      I have all the love and appreciation in the world for enjoying a weekend spent in configuration files. But I feel the need to state the obvious:

      This is a long blog post ending with a preview to "future installments of the guide" to use nix, while almost everything that you need to know with homebrew is `brew install/update/upgrade/uninstall`, and I have rarely run into any trouble with brew, and none at all in recent memory.

      • drampelt 1 year ago
        My biggest issues with homebrew were dealing with versions of dependencies. If major updates for a package came out and you ran a `brew upgrade` (or a new member joins the team and installs it for the first time), it often wasn't trivial to switch back to the old version. Or if two projects have conflicting dependencies, for example one project was updated for imagemagick 7 but another still needed 6, that was an absolute nightmare to manage when using homebrew.

        With nix, each project can define its own dependencies that have no impact on other projects. Combined with direnv, all you need is to `cd` into your project and you have the all of the dependencies at the right versions in your PATH.

        Additionally, while definitely more complicated, nix (with nix-darwin and home-manager) can do way more than homebrew does. You can declaratively define pretty much the entire configuration for your machine.

        I got a new Mac last week and with just a `git clone` and a few commands I had all my CLI tools installed, dotfiles setup, desktop apps installed, and even all of my macOS system settings configured.

        • OJFord 1 year ago
          I'm recently back on macOS for work, and I wanted to love nix-darwin, but just couldn't get it even installed / basics running well enough to start to enjoy configuring things with it. The whole flakes mess really doesn't help.

          (Maybe if you're already running NixOS and familiar with the latest it's a lot easier.)

          I couldn't even uninstall it cleanly, since the Mac was new I gave up after some time and decided it was easier to reinstall macOS (which takes several hours but at least I can just leave it and then know that it's done).

          So I'm back to (purely) brew (and scripts to `defaults write` etc.).

          My frustration with brew is that it's getting increasingly opinionated, and those opinions are not familiar to me from any other OS/package manager... Like if you want postgres v15 you have to `brew install postgresql@15`, and then even if that's your only installed version it's 'keg-only', which means it's not on your PATH, and their suggestion is to dump some stuff at the end of your ~/.zshrc, which aside from the fact you're not using zsh and they could tell that, just seems dumb.

          Then there's python & npm packages... They're deprecated and being removed as independent formulae, so don't do it like that. You're not allowed to install them with the python/node formula you installed, so don't do that. So what do you do, `python -m venv ~/system-python-venv` or something, activate it, and install in there. And now remember to activate that every time you want to use a command that happens to be a python package so you had to install it there. Or dump it in the end of your zshrc, I guess!

          • pxc 1 year ago
            The hardest part of Nix module systems for foreign operating systems, like Nix-Darwin and Home Manager, is absolutely installing them. The difficult bits are the bits they don't control— the parts where they plug into the underlying OS.

            If you wanna give Nix-Darwin another go, I'm happy to help. Feel free to hit me up in the main Nix / NixOS channel or the Nix on macOS channel on Matrix. Getting everything working shouldn't take long with a little guidance.

            (I can also help you get it cleanly uninstalled without reinstalling macOS, if you come away unsatisfied. I have manually uninstalled (i.e., not using the uninstaller) before.)

            • JamesSwift 1 year ago
              Any advice on getting the determinate installer and nix-darwin (via flakes) to be more seamless together? I have a decent setup, but the install/remove is clunkier than it needs to be because

              1) on install, nix-darwin complains about the nix.conf that determinate sets up

              2) on uninstall, determinate complains about nix-darwin being installed

          • wenc 1 year ago
            I have used brew trouble free for many years.
          • NewJazz 1 year ago
            I tried setting up nix-darwin with home-manager, but it just made the system more confusing to operate. Ended up using home-manager standalone without flakes. Works like a charm.
            • JamesSwift 1 year ago
              I stuck with home-manager standalone for many years, but after setting up other nixos configs I found myself wanting to 1) align systems more closely and 2) manage more system-level stuff on darwin. It took some time to rework my standalone modules to nix-darwin modules but overall I'm really happy with the result.

              I run everything through an idempotent 'rebuild' script, so I don't really notice any day-to-day difference between nixos, standalone HM, or nix-darwin.

              • earthling8118 1 year ago
                With or without flakes works nearly identically if it is just home-manager configurations
              • dlachausse 1 year ago
                That's pretty cool that it can install Homebrew packages. Can anyone speak to how well that actually works in practice?
                • pxc 1 year ago
                  I use it to install a bunch of Homebrew casks and a small number of regular packages to support those casks. It works perfectly well!

                  My biggest annoyance is that Homebrew is really slow; the Homebrew part of my Nix-Darwin rebuilds usuay takes 3-5x as long as everything else combined. Homebrew is really slow even when it has nothing to do.

                  The only caveat worth mentioning is that the module built into Nix-Darwin doesn't support installing Homebrew itself. Instead you tell it the prefix for an existing Homebrew installation.

                  (There is an out-of-tree module for installing Homebrew as well, but I haven't tried it.)

                • caiusdurling 1 year ago
                  Extremely well, even supports passing arguments (`--HEAD`) through and integrates with services for casks too, so it can restart things like postgresql when homebrew updates it.

                  Having nix-darwin uninstall brews not declared in the flake makes me stay honest about keeping my configuration up to date as well, if I've just `brew install x` to try something it'll get removed next time I apply my config. Needs adding to the flake to keep it installed persistently, which in turn means my config tends to be up to date.

                  • JamesSwift 1 year ago
                    > Having nix-darwin uninstall brews not declared in the flake makes me stay honest about keeping my configuration up to date as well

                    Note that you don't need nix-darwin to achieve that. I keep my homebrew stuff separate from nix but still "keep myself honest" with this:

                      HOMEBREW_NO_AUTO_UPDATE=1 /opt/homebrew/bin/brew bundle --file="$HOME/Brewfile" --cleanup --no-upgrade
                  • JamesSwift 1 year ago
                    I prefer to keep most of my homebrew stuff (especially casks) in a nix-managed Brewfile with some logic about when to run/update.
                  • hazebooth 1 year ago
                    Without reading the article: I've used Nix on macOS without nix-darwin or home-manager for some time now. I define my packages in a flake.nix that exports an environment and I use install using `nix profile`.
                    • pxc 1 year ago
                      That's a great setup for package management. Stuff like Nix-Darwin and Home Manager start to shine when you want to also do some configuration management. For just package management, your approach is probably better in that it's simpler.
                    • dudus 1 year ago
                      I could never get into nix on Mac os. Maybe it's a different thing if you use nixOS but I'm not willing to make that jump.

                      It seems the clear barrier to entry to nix is UX and to an extent the custom language they use. Maybe this problem can be solved with LLMs. We need an LLM fine tuned to write nix language.

                      • thomastjeffery 1 year ago
                        The language itself isn't as challenging as the overall structure of NixOS/nixpkgs itself. It's a monolithic source-tree of interdependent "derivations". The entire notion of "package" has been thrown halfway out the window. There is logic and reason to the madness, but it's really difficult to find your bearings.
                        • earthling8118 1 year ago
                          So the barrier to nix is... nix? No, the language is not the problem. It is not a particularly difficult language at all. There are plenty of actual problems to address, but the language isn't the issue.
                        • 1 year ago