Going declarative on macOS with Nix and Nix-Darwin
nixcademy.com
nixcademy.com
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).
So upon receiving my macbook I used the migration assistant and ticked everything, and to my surprised I've spent less than an hour getting this new machine up to speed. It moved everything including all my settings, apps, configurations for those apps etc. The only issues I've had is docker didn't move across, and I've had to manually download universal binaries of a few intel apps. It has been completely flawless.
I don't see the value add for the use-case you describe of machine migrations when Apple's tool for this works so well.
Dev environment issues are a thing of the past, once you’ve defined your configuration.
If something is broken with a package, I don’t have to figure it out myself —- I just rollback, wait for someone to fix it upstream in nixpkgs and pull down the patch later.
It's about confidence in your ability to quickly bootstrap a productive system and the relative freedom/security that flow from knowing it.
When you know you can be productive this quickly without access to a backup or a working device, you have relative freedom and security from a decent spectrum of manufacturing defects, hardware failures, disasters, accidents, thieves, and so on.
This is the same for macOS? I’ve done that twice in the last couple of years and it was just a matter of letting the migration assistant run and letting Homebrew install the list of packages exported from the old system.
This is not to say anything negative about Nix, only that this particular point doesn’t seem like a big selling point for something I do every few years.
Nix smooths that out, which is great for a single user with multiple devices but even better on teams. Instead of coordinating devices individually, you can update Nix environments and push them out to everyone at once. The build environment is self-contained, isolated and updated silently alongside the rest of your repo. On larger teams, that saves a lot of configuration headache.
This is the "killer app" of Nix for some people. I've got a lot of machines, spread out between a variety of usecases. With Nix, I can have individual module files for my desktop apps, my gaming software and my terminal configuration, then link them into the various machines that need it. Once it's fully set up, you can essentially manage the environment of dozens of different machines in a single Git repo.
Nix will frustrate people because it doesn't offer a lot of imperative or immediate solutions to things. If you can handle the learning curve though, you'll be hard-pressed to find a more comprehensive package management solution on any OS.
The docs[2] are very helpful!
[1]: https://github.com/Homebrew/homebrew-bundle
[2]: https://daiderd.com/nix-darwin/manual/index.html#opt-homebre...
It also means you aren't completely out of luck if you get lazy and don't test your backups for 6 months only to find out they stopped working after you ran some `blah blah update/upgrade` command.
Also not clear on the backup risk - why would a disk snapshot stop working because you've updated with blah?
It feels like every Nix post that gets on Hacker News has a version of that claim, yet it’s seldom expanded on. In this article, the author throws that in with zero explanation and never revisits it. In other words, it’s opinion and not fact, which is something I do not want conflated in a technical post.
I wish these unproductive software animosities would cease. I don’t care if you use Vim, Emacs, Helix, Windows, macOS, Linux, iOS, Android, or Symbian. Use whatever works best for you and let everyone else do the same. If you have a specific point to make about why a piece of software should be avoided¹, make your argument and let people judge it, otherwise let it go. Why do you feel the need to throw shade on anyone else’s work, especially open-source software? We’re supposed to be a community, not be backstabbing each other.
We’re talking about package managers, here. It’s a bloody tool and you’re treating it like the worst parts of sports fandom.
¹ E.g.: You may feel strongly that Chromium browsers should be avoided because they give Google more power and that’s a risk to the open web which itself becomes a detriment to society.
The thing is, everything is tradeoffs. In some ways I'm sure Nix is better than homebrew.
If you want to compel me to try it, tell me why you think it's better than homebrew so I can understand if it solves problems that I also have.
That's what bothers me, I know not everyone uses my stack and I do love hearing about what others are doing differently but please please please tell me why you think it's better.
Simply saying "Vim is better than standard editors" is pointless, saying "Vim keyboard shortcuts have an extremely steep learning curve, but, once the new way of thinking becomes second nature to you, you will find that you can do things far faster than before. This is especially useful for me personally as the 'context switching' from mouse->keyboard->mouse->keyboard->mouse was an extremely limiting factor for how quickly I can work and Vim (in particular Vim keybindings -- I use them in VSCode today) allows me to keep my fingers on the keyboard for more time before I do something which /requires/ the mouse, this makes me more productive. That said, the only way to learn that was to force myself to use Vim and no other editors which resulted in what was probably a 2-3 week period where I was completely useless, but, ultimately 15 years later I'm sure I've made that time back tenfold."
As you’ve already stated, it’s an opinion and not a fact. I wouldn’t take posts like this so personally. Instead, use content like this to help you explore new tools. If you like it, great! If not, move on. Simple as that.
If you’re new here, people can be very passionate about their tools.
I’m aware. It’s not a coincidence that I started my examples with Vim and Emacs, the classic flamewar. There’s nothing wrong with being passionate for something, that’s not the argument. My point is that just because you like something you don’t have to be against an alternative. Nix and Homebrew, Vim and Emacs, these are parallel tools which can coexist, not rivals in a reality show.
> I wouldn’t take posts like this so personally. Instead, use content like this to help you explore new tools. If you like it, great! If not, move on. Simple as that.
There’s nothing to take personally, and I do explore tools which interest me.
I feel like you haven’t read or understood my point at all. You’re ostensibly disagreeing while making the same point. I’m advocating precisely for the unwarranted negativity to stop. If you want to talk about why you love something, do, there’s no need to send subtle jabs at something else other people are working on and sharing for free. That’s incredibly demotivating for developers and leads to burnout, for nothing.
You can BS enough, but then you have to take some s** back if someone calls you out for making such statements :)
You should be able to simple use:
nix-env -I <package_name>
Or (new flake enabled CLI tools):
nix profile nixpkgs#<package_name>
That's quite close to other package managers. You still have the massive nixpkgs repository and tools like nix-shell as an advantage.
I still have both installed as the union of their packages is better than either in isolation, but I really like having a good idea of what I have permanently installed (and why) in my nix config files, as opposed to re-spending 5 minutes in the brew docs to remember the brew incantation that will give me a reverse dependency tree and try to sort out whether I can uninstall something without breaking something else.
The other solution to this and the other is shell aliasing, make "package manager rm" uninstall regardless of the package manager, and you don't need to remember
The author should have taken the time to state that homebrew doesn't offer features such as ... "environments" or things that help with build reproducibility. A bit unfair, though, because that was probably never Homebrew's mission.
Depends on the wording. It’s perfectly fair to say “I use Nix instead of Homebrew because the former supports X which is useful to do Y”. That way it’s not important if Homebrew intends to have Y or not, it just clarifies what the author cares about in a package manager and the reader is better informed if they care about the same things.
Or they could’ve not mentioned Homebrew at all. There’s zero positives to that sentence in that post.
EDIT: LatticeAnimal answered it. You can’t use the cache with a custom directory.
And it has to be global because the whole point is that there’s only one place and all derivations are shared between user accounts. If everyone had a ~/.nix, hard drives would explode on multi-user systems.
¹ https://www.pathname.com/fhs/pub/fhs-2.3.html#OPTADDONAPPLIC...
² https://en.wikipedia.org/wiki/Filesystem_Hierarchy_Standard
The real reason for it are libraries. The binaries that are packaged in /nix/store very often depend on at least glibc and many other libraries. Their path is hardcoded to /nix/store/...
Changing the path would require recompiling, which also means all the caches that were generated would have to be purged and everything would need to be rebuilt.
Though in my limited experience I was able to also use a symlink. I got a warning that some thing could break but all things I was interested in continued to work.
Seems like an unavoidable consequence of how modern software is built
Admittedly supporting that would require updating how all the tools are built and not just defaulting to Whatever Linux Does™, which is probably too much effort to justify in this case, but it is hardly an unsolvable (or even an unsolved) problem.
(import (fetchTarball "https://github.com/NixOS/nixpkgs/archive/nixpkgs-unstable.tar.gz") {}).go_1_21
where you had `pkgs.go` before (in your shell.nix or wherever).I am certain there are some exceptions and edge cases to this, but in my experience nixpkgs is the largest and most up-to-date repository of all, by a wide margin. Did you use nixpkgs-unstable or a stable release?
I’ve tried Nix on a Mac half a dozen times. It always ends with frustration.
Homebrew works amazingly if you actually want to be on a Mac. If you HATE everything about MacOS and Apple and someone forced you to use a Mac, then use Docker and Nix inside of that.
Nix should never be used on a Mac. It is a philosophical disaster. Don’t do it. Delete the repos and the world will be better off.
I hate using docker on Mac and have since replaced it with flakes and devenv.
My configuration with a step by step guide (600+ stars): https://github.com/dustinlyons/nixos-config
It's fine if you don't like Nix on Mac. It's fine to not use it and to voice your concerns. But calling it a net negative for the world is uncalled for and in my opinion extremely disrespectful to the maintainers doing an enormous amount of work for free.
On another note: I am extremely happy with my Nix on macOS setup.