6 ms·
Can someone explain what the advantage of Nix is over Homebrew? I hear some stories where brew broke something, but I've never had any issues with it.
by behnamoh 3y ago
Can someone explain what the advantage of Nix is over Homebrew? I hear some stories where brew broke something, but I've never had any issues with it.
- unshavedyak 3y agoFor me it's that my dotfiles and packages are consistent across all my envs. 2 Linux machines, 2 Mac machines. I'm not sure if Homebrew has this - but it takes me a few seconds to spin up a new Mac entirely with everything i want (minus build times lol). With home brew i was fiddling with "oh yea, this package/lib/plugin is missing" for weeks. edit: Also, all repos i have are also consistent. Ie i build my repos with specific versions of npm, rust, etc - all per repo, all consistent across all machines, all managed by Nix. Think node-env or py-env (or whatever they're called), but Nix and cross-language instead of specific to node or python ecosystems.
- nani8ot 3y agoUsing brew on Linux is generally not a good idea because distros have better package managers.
- mikemcquaid 3y agoHomebrew has this. Check out Brewfiles and homebrew-bundle. If you want a (excuse self-promotion) dedicated but simple tool to bootstrap new systems: check out https://github.com/MikeMcQuaid/strap https://github.com/MikeMcQuaid/strap
- 0xCMP 3y agoWhile using `nix-env` or `nix profile` (the new way) are very homebrew-like a huge reason to use Nix is that it is more than a package manager. Things like nix-darwin and home-manager allow you to decoratively define your system config and dotfiles. Because it is a language you can override things in same place you're defining what packages or etc you want. And if you start using `direnv` with it's flakes plugin (enabled by default when installed using home-manager!) you can define a flake.nix which will keep a lock file independent of your system's/configuration's that means anyone with Nix installed should be able to activate a native dev environment with the exact versions of node, python, rust, pnpm, etc. ready to go. It's quite powerful once you become familiar with how to use it.
- flylikeabanana 3y agoNix aims to solve a much more general problem than homebrew. If all you want is to get some packages on your system, there might not be that much in Nix compared to brew for you. The zen of Nix is that building packages is expressed as pure functions, where inputs, outputs, and side-effects are carefully managed. Thus, if you have specific build, packaging, or environment configuration to do, nix can be really helpful. Since everything is in code and every generated nix configuration is effectively isolated from the rest, it makes rolling back to previous configurations trivial in the event something goes wrong. That, and you can VC a config, and in general once a package is properly expressed in Nix it more or less solves the "works on my machine" problem
- solardev 3y agoI don't understand :( Is nix like a npm lockfile then, carefully controlling specific versions of packages and dependencies on a per... what, per-machine?... basis? Or is it kinda like a Docker container that can contain isolated programs? Or something like pyenv or nvm that can let you switch between version sets?
- Cu3PO42 3y agoIt's not just a lockfile, though the 'Nix flakes' feature does have a `flake.lock` file. It locks the revision of your 'inputs', i.e., repositories containing packages. The most common and important input is `nixpkgs`, which is kind of like the default package sources on a Linux system. It has glibc, bash, coreutils, etc. but also an extremely large number of other programs that have been packaged. And in a particular revision of nixpkgs, any package has exactly one version. So, yes, the versions of all packages can be locked. As for the granularity: that really depends on how you want to go about it. If you manage a NixOS system (a Linux distribution built on Nix), you can control the versions on your system. But any project could have its own environment entirely. In fact, in any project you can have multiple versions of nixpkgs if you really wanted to.
- Rucadi 3y agoSimilar to npm lockfile, basically you can install an specific version of a program globally if you want, but it's not recommended, and you can have multiple configurations for different projects or folders with an specific version of tools/apps-
- hamandcheese 3y agoIf you are only using nix as an imperative package manager just like homebrew, there is little advantage. One area where nix shines is that you can write nix code to build a reproducible dev environment for your project. You can think of it kind of like if you could use a Brewfile to build a virtualenv that doesn't touch your system at all. I like this a lot because it makes dusting off old projects way easier. I don't have to worry about the state of my system, or reverting to an old version of ruby, etc. to get the old project running again. Nix is also much more powerful than a Brewfile. You can override the versions of dependencies or even package your own custom dependencies and use those in exactly the same way. The learning curve is steep, but once you learn you have an incredible amount of flexibility and power all built on a robust foundation.
- nvy 3y ago> I don't have to worry about the state of my system, or reverting to an old version of ruby, etc. to get the old project running again. But wouldn't you want to update your project to a new(er) version of Ruby in that hypothetical? There have probably been security updates along the way.
- pxc 3y ago> But wouldn't you want to update your project to a new(er) version of Ruby in that hypothetical? Perhaps because it's in maintenance mode and what you really need is just to be able to run it to compare its behavior with that of its replacement, or because you want to perform the upgrade by replacing code that relies on deprecated APIs in an incremental way, in a copy of the codebase that still runs and passes tests at each step along the way. Or maybe you're a scientist and you want to run the original code because you want your tests to have the exact same performance and other characteristics as the code used in the original paper, so you want to avoid compiler/interpreter optimizations that have come out in the meantime.
- nvy 3y agoThose all sound like legitimate but very niche use cases. I don't see the mainstream appeal of Nix.
- Cu3PO42 3y agoNix has a fundamentally different approach to package management. Homebrew will install everything into `/usr/local/` or `/opt/homebrew` depending on your architecture. From there, all installed software can discover all other installed software in a standard location. If, for example, you wanted to link 'mimalloc', you may find it in `/opt/homebrew/lib/mimalloc.so`. This is roughly how package management on Linux, BSD and presumably other Unices has always worked. On the other hand, Nix installs software into `/nix/store/longhash-pkgname`. By default any given package is not aware of anything else you have installed, unless said package explicitly referenced the other during build time, including the exact version of the package. This makes it possible for every package to get exactly the version of a dependency that it's known to work with and allows you to have different packages working with different versions of libraries. This makes Nix extremely reproducible: once a package works as intended, it will almost certainly continue to work no matter what else you change on your system. On the other hand, I have experienced issues with my system after `brew upgrade`s on multiple occasions. Particularly related to Python upgrades. I still use `brew cask` to install most GUI applications, since the repository for those on macOS is larger.
- paulsmith 3y agoIt's worth noting you can let Nix manage Homebrew for you, too. I do this on my MBP on which I have nix-darwin running, not for regular Homebrew formulae but for casks for GUI apps. In my configuration, I have this homebrew = { enable = true; onActivation = { autoUpdate = true; upgrade = true; }; casks = [ "inkscape" <other gui apps ...> ]; };
- JamesSwift 3y agoI achieve mostly the same on a non nix-darwin setup using vanilla home-manager: home.file."Brewfile" = { onChange = '' HOMEBREW_NO_AUTO_UPDATE=1 /usr/local/bin/brew bundle --file="$HOME/Brewfile" --cleanup --no-upgrade ''; text = '' cask '1password' ... ''; }
- Cu3PO42 3y agoExcellent point, thank you! I use that as well and intended to mention it and then I just forgot. Personally, I've been hesitant to turn on autoUpdate, have you found it to work well?
- flexiondotorg 3y agoI mostly run NixOS but do work on macOS occasionally and being to bring all my familiar home environment, configuration, tools and a multitude of project specific development shells is a huge time saver.
- JamesSwift 3y agoBrew is fine for what it is. Nix generally shines by being a way more general solution to the problem, which means you can take the nix managed version of things and move them across machines/OSes very easily. The main advantage of nix against brew purely as a mac package manager is the ability to easily use versions of things that aren't HEAD (or to use multiple different versions of things for different reasons). Homebrew has a really clunky way to do that, but its much more straightforward in nix.
- emptysongglass 3y agoI'd say brew is the least effective option but people on macOS just deal with it because it's basically the only package manager they've ever been exposed to. Lots of Stockholm Syndrome going around.
- hotnfresh 3y agoHeavy Linux user for about a decade before being given a MacBook at work and realizing how much time I’d been wasting for no reason (well, not no reason—I’m a lot more comfortable & capable on Linux servers than most other developers I’ve known). Have continued using Linux on servers, appliances, and checking in on how Desktop Linux is going every couple years, in the 13ish years since. I have a lot of experience with two major RPM-based ecosystems, with Portage, and with two major dpkg-based distos. I’ve also done a fair bit with Void, and a little bit with Arch and Nix. After switching to Mac, I used Macports for a little over a year before switching to Brew, IIRC. The factors I care about in a package manager, in no particular order: 1) How good’s the UI? 2) How often does it break or otherwise make some kind of bad thing happen when I use it? 3) How bad is my day going to be if it breaks or does a bad thing? 4) How good is the package selection? Brew is easily my favorite, based on that.
- NateEag 3y ago> 2) How often does it break or otherwise make some kind of bad thing happen when I use it? > 3) How bad is my day going to be if it breaks or does a bad thing? Gosh - I've used FreeBSD's package manager, Gentoo, MacPorts, apt-get, ad-hoc bash scripts, brew, nix, and even occasionally manual compilation for package management over the years, and brew is by far the one that's caused me the most pain. Just in the last year of $DAYJOB I've probably had brew break my dev environment at least three times because I installed a new tool and it auto-updated the others when I did that. Maybe I'm holding it wrong, but the others haven't done that to me. Obviously that's not your experience, and I don't intend to dismiss or demean that. It's just shocking to me how different our experiences of brew are. FWIW nix is definitely my favorite packager manager so far. I've been using NixOS on my laptop for about a year, and nix on macOS for package management before that, and it has been shockingly robust. I do not recall a single time a tool I got installed and working via nix has broken on me. Running a Linux desktop has been kind of disappointing in a lot of ways - while they've improved a lot in the last decade, there are tons of ways macOS and even Windows have superior overall UX. But for robust package management, nix has been everything I ever dreamed of and then some.
- ar_lan 3y agoTwo clear examples off-the-bat I can think of is: 1. Nix installs all necessary libraries as well as part of the install path. That is - if you need two versions of a library, you aren't needing to contend with whatever is globally installed. I ran into this a lot with Python stuff, personally. 2. You can install different versions of the same software without needing dedicated version managers. This is immensely useful if you work on several different projects that might be using different versions of tooling. -- But that's just Nix the package manager. Brew does not solve problems of OS configuration, dotfiles management, reproducibility, etc., all of things Nix solves off-the-bat. For example, I mainly use macOS at work but NixOS for anything personal, as well as servers. I can maintain roughly consistent, through code, environments with only minor tweaks per machine. This means I have essentially the same development environment at work and at home for anything in the terminal. Another big benefit is, if anything breaks, you can always roll back with Nix. Or, since it's code, it's very easy to start with a clean slate. I recently changed Macbooks and, with only a minor tweak to account for the ARM chip instead of Intel, I was up-and-running with my entire environment exactly as it was, with the only time accounted for being package download and installation, essentially. -- The main problem that Brew solves that Nix does not (well, it does, but it defers to Brew to do so), is installation of graphical applications. There is an open Apple bug on this issue IIRC - I don't recall all the specific details at this moment, however.
- pxc 3y ago> The main problem that Brew solves that Nix does not (well, it does, but it defers to Brew to do so), is installation of graphical applications. There is an open Apple bug on this issue IIRC - I don't recall all the specific details at this moment, however The issue is that Spotlight doesn't index across volumes other than /, so when you symlink apps into /Applications or whatever from /nix/store, Spotlight won't recognize them. Installing those applications via Homebrew is one way to manage it, but you can alternatively instruct Nix-Darwin to install those applications by copying them out of the Nix store rather than symlinking, which also works.
- semi-extrinsic 3y agoAll these newfangled abstractions like Nix, Docker, virtualenvs etc. are simply because people find it more interesting (and easier to monetize) to build new frameworks instead of learning to use existing ones. As an example, Environment Modules solves 98% of these problems and has been available for more than 30 years: https://modules.sourceforge.net/docs/Modules-Paper.pdf https://modules.sourceforge.net/docs/Modules-Paper.pdf
- grhmc 3y agoI don’t think that’s quite true, though I noticed Eelco didn’t mention Furlani’s work in his 2006 phd thesis on Nix (started in 2003): https://edolstra.github.io/pubs/phd-thesis.pdf https://edolstra.github.io/pubs/phd-thesis.pdf
- mdasen 3y agoFor me, the advantage of Nix is that I can install stuff without worrying about what it will mean for anything else on my computer. I can type `nix-shell -p <package-name>` and get a new shell with that package. Maybe it's something I just wanted to try out. When I exit the shell, it's basically gone (it's still on my disk, but it hasn't changed anything in my normal shell environment). I can have different versions of Python or Ruby for different shells. In fact, I can solve some of the "works on my machine" issues with Nix. I can put a shell.nix file into my git repository. Then when someone else wants to run my Python code, they can use `nix-shell` to bring up a shell with everything I expect to be there. I don't have to tell them "ok, first install version X of Python. Oh, you already have version Y installed? ...well, figure that out and then we're moving on to installing..." It creates a nice little semi-isolated shell with all the things needed to run my thing - and I can replicate that environment on other people's machines. It's also a ton faster than Homebrew when installing things. I was shocked how much faster. My advice (if you're interested in trying it): start small. You already have Homebrew. Install Nix on your machine and then forget about it - until you want to install a new package. Then type `nix-shell -p <package-name>` and you have a shell with that package. Later, you can create shell.nix files. You can commit these to a git repo so that you can bring them to a new machine. I don't personally use it that differently from Homebrew, but there are certainly times when it's really nice to be able to install something without it causing chaos in my system and it's nice to have files written down with the things that I want installed so if I want to reformat my machine, I can get things back up nicely. I'm sure there are more use cases for its semi-isolation, but in the meantime I've been quite happy with it.
- oldbbsnickname 3y agoHomebrew is deceptively simplistic in a "worse is better" way, but their management is arrogant, make poor engineering decisions, and causes headaches at scale beyond individual web developers who don't notice the subtleties of system entropy or configuration management. For example, their recipe system doesn't respect local changes and insists on querying their API "cloud" for package metadata. Useful options for package configuration were removed. Parallel downloading and installation doesn't happen. Every invocation of the brew command is slow, having to traverse ruby and bash. It sends telemetry by default. There are a bunch of side-effects that aren't handled. Formula inclusion is decided not by subject matter experts but by "Wikipedia editors" who decide arbitrarily. Nix solves version and configuration dependency hell problem by allowing multiple versions and configurations of the same package side-by-side. Unfortunately, it also still wants to make system-wide changes on macOS. It also has the "problem" of less wider accessibility because the functional nature is more complex. PS: I have worked in client platform management and engineering at scale.
- grhmc 3y ago> Unfortunately, it also still wants to make system-wide changes on macOS. For context, these changes are: 1. Creating and mounting a volume at /nix for the store 2. A daemon used for isolating build environments 3. A zshrc / fish / bash hook to load a few environment variables (PATH, mostly) 4. (new!) an on-boot Launch Daemon to keep those profile hooks working between upgrades.
- oldbbsnickname 3y agoNo sale. Too much complexity and too many side-effects.
- _v7gu 3y agoThe main advantage for me is that Nix will not run a system-wide upgrade command (that takes quite a while to execute) by default while running a simple install command, causing breakages all over the place