I came across a nearly-month-old Reddit thread about this topic here, and wrote up a long stream-of-consciousness reply that I wanted to reproduce here - both to help drive traffic to that Reddit thread and to garner feedback about what I wrote and my own experiences.
I strongly recommend using home-manager rather than imperative
nix-env -i style commands, and would also more lightly recommend nix-darwin. I have significantly less time with nix-darwin, which is part of why my endorsement is much gentler. I’ve used Nix on OSX since ~August 2017 and nix-darwin only since ~November 2018, and I know I’m not using it to the fullest. I find the latter’s learning curve to be something of an impediment for people who have migrated from Homebrew without a lot of prior Nix experience. To my knowledge, it’s the only way you can reasonably approach the utility of
brew-cask while using primarily Nix instead.
Over time, I’ve managed to shrink from a list of 100+ homebrew packages and nothing installed via Nix to almost-everything with Nix and a few holdouts in Homebrew. My
brew leaves shows only 13 packages today, mostly things that are entirely unpackaged in Nix, or awkward to use vs Homebrew, such as my clinging to
brew services for purposes of Postgres 10.x and not learning enough about
nix-darwin to write myself an equivalent launchd definition.
I definitely also recommend starting your journey by taking a capture of everything you have via Homebrew today, by running
brew bundle dump --no-restart and saving that in
~/.Brewfile. This will allow you to have a point in time capture of that inventory, and also enable the following commands:
brew bundle install --global --verbose --no-upgrade
brew bundle check --global --verbose
brew bundle cleanup --global --force
Judicious use of the first and last can get you moderately close to “declaratively” managing your Homebrew inventory and see how it changes over time. The file is arbitrary Ruby in content and you can easily revise the file to add conditionals for things like your hostname, OS version, etc. if you want to share it between machines.
A few other random pointers:
- I alluded to it earlier, but I chickened out of trying to manage my GUI software with Nix and continue to use
brew caskfor this, YMMV
- It is entirely possible to succeed with the multi-user daemon-based Nix install, including on OSX Mojave. There’s a GitHub issue I can link that has to do with process forking and
curlif other people have problems with this combo, but mine is working happily after that particular triage.
- Get used to scoping out
brew leavesto see what you currently use from Homebrew rather than
brew listwhich will lump in dependencies.
- Start with
brew unlinkinstead of
brew uninstall, don’t just go cold-turkey, especially if you rely on this stuff professionally
- Use some variation of
nix-env -q(I like
-qaP) together with
brew info ...to see if your needed packages are drastically older on Nix, which has happened to me infrequently but non-zero times.
- It’s not strictly necessary, but getting comfortable with writing your own derivations might ease the pain of migrating at the cost of some maintenance burden.
- Try to take some time to learn the semantics of
home-manager expire-generationsif you pick up HM), and keep an eye on disk usage of
/nixat first using something like DaisyDisk or the CLI utility
ncdu. I keep a rolling ~60-day window and don’t automate the cleanup, and I have 10s of GB in my store at the moment.
- Turn on
/etc/nix/nix.confunless you (or another poster) know a good reason not to - it hardlinks duplicate content for you and can save quite a bit of disk space.
If you want to see what kind of insanity is possible for someone who’s really comfortable with this intersection, do some spelunking in John Wiegley’s dotfiles. Even with the experience I’ve mentioned up top, and being comfortable with Emacs/Make/etc., there were still some real brain-benders in here for me.