The Nix Elevator Pitch

Hey,

I’ve recently often found myself in situations where somebody asks “What is Nix?”. It seems like I never manage to actually give a useful answer to that question, at least not in a way that stirs the desired excitement immediately.

What are your answers when someone asks you “What is Nix?”, and how well do people react to them?

5 Likes

I have had different pitches, depending on the audience, but it generally revolves around

For the developer folks:

Imagine [bundler, npm, yarn, composer], but allowing to describe and lock all dependencies of the system, including misc. tooling and binaries external to a specific language’s ecosystem.

For the sysops folks, I don’t have one all ready to say, but it’s close to “imagine a [salt, ansible, puppet], where the builds are described in a functionally reproducible way”, though I often have to ask more about their programming language backgrounds to better suit the pitch. E.g. those already understanding what a functional programming language is need less explaining about the benefits and what it means.

Though, I make sure to point out that this is a limited view, applied to specific problems. Nix is much more and has been applied to a large set of needs!

3 Likes

What I struggle with is the pitch for “why should I use Nix instead of Homebrew?”, i.e. use as a general macOS package manager.

What I struggle with is the pitch for “why should I use Nix instead of Homebrew?”, i.e. use as a general macOS package manager.

I guess something along the lines «imagine being able to trivially sidestep any package conflict unless you actually want to link the corresponding libraries into the same executable»

1 Like

Yeah I mean, I know why I like it, it’s trying to convince friends and coworkers where I face an uphill battle since everyone defaults to Homebrew. And when used as a general package manager, actual package conflicts aren’t common.

And when used as a general package manager, actual package conflicts aren’t common.

Oh wow, on every apt-based Linux system I ended up with at least one situation where I had to untangle a package conflict (which is not a common situation, but once is already annoying…) Maybe people don’t actually install much stuff via Homebrew… in which case I guess it would be indeed a hard task to convince them to use a better tool to manage packages when they don’t do enough with packages for the effort to pay off.

My pitch:

Nix is a powerful package manager. I can confidently compile and run multiple incompatible versions of software simultaneously. I can build projects from years ago. I can package large projects from different ecosystems (python 2/3, c/c++, go, javascript) and be confident they will not interfere with each other. I can try bleeding edge software with no risk to it interfering with my system. It is faster and less hassle than juggling various Docker containers and VMs. It protects me from dependency hell.

But overall: it makes me more productive. It is my secret weapon to manage the complexity of software development.

9 Likes

I’ve used

Imagine “Works for me”, but for everybody.

as a quick, lighthearted shorthand before.

8 Likes

Indeed. I used Homebew for ~8 years and rarely had a package conflict. What convinced me to use Nix (when I was still primarily using a Mac) was being able to set up custom development environments with shell.nix + nix-shell.

I actually tried Nix one time before and fell into the nix-env -i foobar trap and dismissed Nix as ‘is slow, gobbles up large amounts of memory’.

2 Likes

“Think like a mix of Git and a time machine for your package manager”

1 Like

I’m really fond of this characterization, because I actually do straight-up run into the problem of dealing with the language ecosystem and the system at the same time. I think most developers do, but they just consider “install postgres, install nginx, install floki, install x, y, z” to be part of the setup process that they have to go through.

I first realized the real power of Nix when I created a devops environment that installed all of the tools that I needed (ansible, terraform, etc) at versions I knew, on any machine I needed it installed on.

3 Likes

Here’s my attempt (for the nix package manager on macOS):

Have you ever written a custom script which had dependencies? It could be a ruby script requiring a particular set of gems, it could be a shell script that requires up-to-date versions of GNU’s coreutils, or it could even be a bash customization that require a third party library such as bash-preexec.

If the answer is yes, you probably know how fragile this can be, for example many of your customizations may break after an OS update, it’s messy trying to share such scripts/customizations with friends (because they have to recreate your environment, and maybe they do not want GNU’s date command to be the first one found via PATH), etc.

Nix allows you to create a central repository for your customizations with explicit dependencies, and without having to install these dependencies into the global namespace/PATH.

If the above doesn’t appeal to you, I’m inclined to say that sticking with homebrew is better, because it has a much lower learning curve, and overall it works pretty good. Two exceptions though:

  1. There is no way to get a list of explicitly installed packages. You can use brew leaves but this may include orphaned dependencies or it may hide explicitly installed commands, because something else installed depend on them.

  2. There is no simple way to uninstall a package with dependencies. The way to do this appears to be to first uninstall all dependencies of the package, ignoring that other stuff may depend on it, then uninstall the root package, and then re-install missing dependencies.

If you find the above unsatisfying, nix should appeal to you.

1 Like

I think the better solution to a development environment that require a database, web server, etc. is to use something like vagrant (not nix alone).

That said, I enjoy being able to use nix-shell -p «package» to quickly install something for testing/playing around. It feels cleaner than installing it globally, and possibly forgetting to uninstall it again (and yes, I know some say nix-shell is not meant for this, but I know of no better option).

Yesterday I tried to convince my dad to switch from Homebrew to Nix. In the end he admitted Nix was “elegant” but I was unsuccessful because of the learning curve and UX of using Nix.

FWIW he says he doesn’t have issues with package conflicts (he doesn’t have very many packages installed), though I did notice he has a few orphaned packages (libraries with no dependents). He also seemed to think nix run was clever, but apparently not compelling enough.

The “write a script that includes its dependencies” is something I think is cool but it turns out he doesn’t write very many scripts.

He seemed somewhat interested by the idea of using it to manage per-project dependencies, but his next question was “does it run on Windows?” because apparently he’s the only person using a Mac working on the product he was thinking of. My best answer was “maybe using Windows Subsystem for Linux? I’ve never tried”, though even if that worked I doubt he would be inclined to convince his coworkers to fire up a Bash shell to muck with dependencies. I also had to admit I’m not sure if there’s any reasonable IDE integration yet.

1 Like

“Think like a mix of Git and a time machine for your package manager”

I’ve also used this Git analogy with fellow sysadmins,
after having seen it emphasized here:

1 Like

Here’s mine. There are no tall buildings here, so it spills out of the elevator.

“Nix is a package manager with a configuration management system baked in, a thing of alien beauty which does it the absolute right and otherworldly way, totally unlike your garden variety ones. After Nix, Ansible&co feel like an imperative shellscript, APT&co feel outright impotent and pip&co feel like a hacky pile of nuisance that should not even exist. Think truly declarative configuration, virtualenvs not tied to language ecosystem and [something that massages a suspected pain point of a listener, like ‘user-installable packages’, ‘builds are reproducible’, ‘the state of the whole distribution is just a git commit’, ‘all reverse dependencies just get rebuilt’ or ‘multihost tests can be written in under ten lines’.”

4 Likes

This is what I used several years ago at FOSDEM when we had our own NixOS stand: https://sandervanderburg.blogspot.com/2015/02/a-sales-pitch-explanation-of-nixos.html

It worked fairly well in most cases, but as usual: advertising Nix properly is a challenge and also depends on the background of your audience.

1 Like

“Nix is like Arch but with an undo button” is what made me try Nix.

I liked having the new software’s updates quickly with Arch but I got caught with my pants down a couple of times at work with updates breaking my system and not being able to work. I guess I could have used file-system snapshots.

1 Like

True. In full honesty, I use my nix shells for the command line tools, but services that I need to run I typically put into a docker container.

BTW the “better option” here is nix run. nix-shell -p foo sets up the environment as it would for building foo, so all of foo's dependencies are in your PATH and all of the other environment vars are set too (I count 23 env vars containing NIX), but nix run produces an environment much more similar to what you’d get if you simply installed the package (e.g. it basically just prefixes your PATH with the appropriate directories from the specified package).

That said, nix-shell replaces your normal shell initialization files and nix run doesn’t, so depending on how your .bashrc is set up you might override the PATH. For example with my setup, echo $PATH in a nix run shell starts the path with /usr/local/bin before the nix-provided path value, because my current .bashrc unconditionally prefixes my PATH (which I really should fix).