top | item 44098605

I think it's time to give Nix a chance

148 points| pacmansyyu | 9 months ago |maych.in

151 comments

order
[+] taosx|9 months ago|reply
Nope, not yet. I tried that 3 times, once for my mac, then for my linux and once for a project. Every time I gave it a solid try found it lacking so I made a note to wait a few more years. The promise of reproducible systems is so hard to resist but nix brings crazy complexity (not all of it necessary), I'd prefer a system where their package repo has 4 packages but it makes it easy enough to me to bring other packages.

Writing nix is like writing functions but in order to remember the arguments and fields of those arguments in another file that you can only access through your browser. Look at any nix file, and tell me where each variable is coming from.

[+] ThatMedicIsASpy|9 months ago|reply
I have tried NixOS and the out of the box experience isn't bad, neither on my main VM nor my notebook. Everybody points you to flakes and flakes point you do use the unstable branch of nixos and that is where I say no. Then you learn a bunch of things along the way like upgrading replaces your stuff and you have to start again.

I've moved to Atomic desktops and can't name anything I am missing. For dev stuff there are containers.

[+] IshKebab|9 months ago|reply
Yeah I think this is a big flaw of declarative systems. I see a Nix derivation that contains `foo: bar`. How do I know what this does? It's pretty much impossible to know without learning all of Nix, because anything can access it.

If it was a function call you could just go-to-definition.

Environment variables have a similar issue. It's often hard to know what they do because they could be used by basically anything at any time.

[+] snapplebobapple|9 months ago|reply
Its not that practical. I cr#ated a nix file to roll a new jellyfinmediaplayer client in nix and it worked until s(me update broke it but the audio and a few other things needed finding obscure nonsense and specifying it to work passably. Its been replaced by fi e sentences remnding me what to click installing bazzite and it works rock solid for very mnimal additiobal setup time
[+] urlwolf|9 months ago|reply
I moved to nix around Nov last year and couldn't be happier, the motto 'nix fixes that' is true. First time I can say linux is trouble free. Upgrades are painless. Dev environments, reproducible. Largest repository of packages in the linux world. Next to zero time wasted configuring things. Foundation LLMs now know enough nix to get you out of trouble most of the time. It's perfect as a linux experience.
[+] TeeMassive|9 months ago|reply
Until your use case hasn't been deciphered by a Nix scribe and then you have to fight the magic.
[+] sepositus|9 months ago|reply
Welcome to the honeymoon phase. Mine lasted about a year. Eventually you will have to leave the comfortable area of "those who have done it before" and engage with some long, unwieldy, mostly undecipherable stack trace.

When I asked a long-time Nix vet why he thinks people leave, he provided the most insightful answer I've seen yet: they just don't try hard enough.

[+] zachlatta|9 months ago|reply
Can you link your dotfiles? I’ve been having trouble figuring out a good way to structure mine
[+] OscarCunningham|9 months ago|reply
I recently installed NixOS on my laptop after years of using Debian, and the main difference I noticed was that it's much easier to keep everything clean.

For example with Debian I might do something like try to get my GPU to work by installing nouveau, try various configs, then uninstall nouveau and install the Nvidia proprietary drivers. But then when I finally got the GPU working, I'd worry. Are some of those config changes I tried for nouveau still affecting my system? Has all that mucking around left my GPU forever in a suboptimal state?

With Nix, it might take just as much tinkering to get the GPU to work. But once I'm done, I know that my system is exactly as I've defined it in configuration.nix. Anything else I tried along the way will just sit inertly in /nix/store until the garbage collector wipes it away.

[+] layer8|9 months ago|reply
I don’t know. My concept for reproducibility with Debian is a backup of /etc and the list of installed packages (the output of `dpkg --get-selections`). It’s also not difficult to diff one’s /etc with a pristine version, though I haven’t actually needed that in many years.
[+] pabs3|9 months ago|reply
The Debian cruft-ng package, plus package list diffs, can identify problematic state you have added to the system.
[+] Altern4tiveAcc|9 months ago|reply
This article felt like a strong argument against Nix rather than in favor of it. The complexity it brings is just not worth the gains for the majority of people that I know. No, most people won't be happy that Nix breaks dynamic linking.

Docker with a Debian Stable base will solve the problems listed for most users, with 1% of the time investment. The author used Nix for 8 years, and I'm not surprised it looks a bit simpler to them now.

[+] codethief|9 months ago|reply
Ubuntu user of 15 years here (+ a couple years of tinkering with RedHat, Arch & Gentoo before that).

I tried to learn Nix (the language) a couple years ago, didn't like it and got nowhere. Now, two months ago I heard I would be getting a Windows machine at my new client, so I really wanted a way to deterministically generate a Linux VM that worked & felt exactly the same as my usual setup. So I thought back to Nix(OS) and this time I skipped trying to learn Nix and just tried to absorb it from examples and code snippets I would find online (very reminiscent of my experience with Emacs many years ago). Often I would also ask Gemini to explain things to me. Only a few afternoons later I had a working VM[0] that looked and felt exactly as the desktop environment I have carefully curated over 15 years. Now, several weeks later, I also have built a live CD image with that same config and will soon roll out my Nix config to all my Ubuntu machines & Debian servers. I won't look back.

I won't deny, though: I still don't like the language too much and I think it is tied too much to building an OS, as opposed to anything else. Documentation is sparse and mediocre at best. But overall it's alright! Things are usually not that complicated, and most of the time they just work! (And if they don't, it's surprisingly easy to navigate the nixpkgs source code and look up what's happening under the hood.) In any case, my new Nix config is so much better than the set of bespoke Bash scripts I've written over the years to (reproducibly?) configure my Ubuntu desktop with i3wm for me.

[0]: nixos-generators is magical when you first try it! https://github.com/nix-community/nixos-generators (Fine print: Of course with the benefit of hindsight I now know that it's merely a dumb wrapper around things that Nix provides out of the box but oh well.)

[+] Modified3019|9 months ago|reply
My recent experience being tech support for family and trying to make available some sort of digitized preservation of family photos/history, has been impressing upon me the need to get away from Rube Goldberg systems that only I could possibly understand and modify. My primary filesystem being ZFS already makes having my stuff be accessible to others after my death a bit unrealistic. (Part of my strategy, will be physical redundancy with archival disks and HDDs, and even paper for text information)

I’m forever intrigued by the promises of nix, but I have finally accepted that I am not the target audience for what they have built. The nix language is fundamentally at odds with general purpose usability. Even using the package manger on other distros is fraught with gotchas.

On an off topic note, I find it fascinating how both my father and grandfather, who are/were quite technically competent, seem to become increasingly and possibly willfully helpless about computers as they get older. I find myself wondering if at some point I will also experience exhaustion of whatever internal energy is needed to fuel technical fluency.

[+] microtonal|9 months ago|reply
The nix language is fundamentally at odds with general purpose usability.

I have contributed or tried to contribute to many distributions (heck, I even worked for a commercial Linux distribution when I was young) and contributing to nixpkgs was an order of magnitude easier than other distributions. Part of it was the GitHub/PR-centered workflow, but the other part is that Nix is a small functional language and the package definitions are not in some arcane weird format like RPM spec files or Debian rules. Also, Nix makes it much easier to refine a derivation/package without actually having to install it on your system.

[+] weinzierl|9 months ago|reply
What is the supply chain security story with Nix packages?

I stick mostly to reasonably popular Debian packages. My thinking is that if one of them has a serious vulnerability it will get fixed quickly or a lot of people have much bigger problems than me. I always worry about niche package systems, where it should be much easier to sneak in something malicious and it could linger there for a long time undetected.

[+] __MatrixMan__|9 months ago|reply
As I see it there are three components of software supply chain security:

- is this actually the binary that comes from that code?

- is that code trustworthy?

- is this binary trustworthy?

Nix focuses on the first. If you can solve that problem, there's still nothing preventing bad guys from publishing malicious code, or from distributing malicious binaries which did not actually come from the code that they claim to, but it forces them to act in the open where they're more likely to get caught--anybody can verify that the correspondence between code and binary doesn't hold.

So if you're worried that one dark day, `curl whoever.com/whatever.sh | bash` will suddenly contain malware when it didn't before, using nix instead will protect you... until you manually approve the malicious update. It's up to you to come up with reasons why you should or shouldn't do that, but at least there will be a commit in your code where things went bad.

If you're wondering whether whatever.sh is safe in the first place, and you want some council of elders to pinky promise that it's safe to run, then I don't think the nix ecosystem has much to offer you.

Personally, I think that solving the latter problems without a robust solution to the first problem is sort of a band-aid solution. So I'm a big fan of the nix approach to supply chain security, but it's important to be aware of what you're not getting, which is a promise that any bits are trustworthy in the first place.

[+] elsjaako|9 months ago|reply
The source code is retrieved from the official source of the package, and checked against a hash that is stored in the package definitions. All the package definitions are stored in a large github repository, and they are "code reviewed".

For example, you can see where the xz sources get pulled from in the src section here:

https://github.com/NixOS/nixpkgs/blob/nixos-25.05/pkgs/tools...

As usual, wherever you get your software, if someone at the source sneaks in something malicious and no one notices it it gets in there. NixOs has no special mitigations against that (AFAIK).

But you can be reasonably sure that the binary you have matches the official source of the software, with maybe some reviewed patches to get it to work in Nix's environment.

The binaries are cached, so you don't have to build everything yourself. There is a command to rebuild the software from source yourself. Most packages are reproducible, about 95% of the distributed gnome version: https://reproducible.nixos.org/nixos-iso-gnome-r13y/

[+] mplanchard|9 months ago|reply
An unexpected benefit of nix for me was CI caching. It’s easy to set up S3 as a binary cache, and then anything you can express as a nix derivation can be cached so that if nothing has changed, it avoids a build.

One fun example is the test database: five years of accumulated migrations were relatively slow to run in various portions of the pipeline. I made a nix derivation that runs postgres, runs migrations, seeds some test data, runs some tests, and then saves the data directory into $out. CI jobs can then load the DB by building that derivation and copying the data files into a local directory. If no migrations or other dependencies have changed, this is virtually instantaneous.

[+] bigyabai|9 months ago|reply
My last gig was at a place where a guy basically wrote his own job security by reducing a 1hr 40min JS build pipeline down to 2 minutes with Nix caching.
[+] cjbgkagh|9 months ago|reply
Interesting, I have my own hacked together caches to greatly speed up docker setup, having a cache at this level may speed things up further in a cleaner more maintainable way.
[+] kombine|9 months ago|reply
I use Nix and Home manager to keep a consistent terminal development environment (Neovim and friends) across my personal computers and on the HPC cluster. I never used NixOS. It took me a while to craft a working and flexible config, but since then I rarely touch it and only update packages once in a while. It works great for my needs.
[+] lemonwaterlime|9 months ago|reply
It is possible to use nix simply as a better Homebrew—one where you can update packages without all of your system potentially breaking from package updates. That has happened to many people with brew and it no longer happens to me.

That means `nix-env -iA <packagename>`.

Is this approach using the full power of nix? No. But in a “worse-is-better” kind of way, just doing this has given me a more stable system than I had with Homebrew. And that’s all I wanted from nix. Flakes and nix-shell are just additional things that I’ve gotten some benefit from over time.

[+] spenczar5|9 months ago|reply
Something I have always wondered about is how Nix interacts with my editor and language servers.

I use emacs. The emacs LSP mode starts up a language server process for a language like Python or Go. If I use Nix to manage development dependencies like my compiler, linting tools, and even language-specific dependencies, then how do I get the LSP and emacs to use the correct Nix-y set of dependencies? To make things extra complex, note that I often work on multiple interdependent projects concurrently; I imagine that makes things even gnarlier.

Is there a sane way to manage this sort of thing? Do I end up managing a per-project installation of emacs??

[+] krapht|9 months ago|reply
I tried to give Nix a chance but I never figured out how to package dependencies that didn't already have a derivation written for them.

Particularly since I do a lot of ML work - I never figured out how to handle mixed Python/C++ code with dependencies on CUDA.

It's just way easier, even if not reproducible, to build an environment imperatively in Docker.

[+] sepositus|9 months ago|reply
The most common answer I've seen is that Python packaging just "doesn't do it right" so it's impossible to get a clean Nix experience with them. Which, to some degree is true, but it also reveals the opinionated nature of Nix and why it often falls flat.
[+] unignorant|9 months ago|reply
I do a lot of ML work too and recently gave NixOS a try. It's actually not too hard to just use conda/miniconda/micromamba to manage python environments as you would on any other linux system with just a few lines of configuration. Pretty much just add micromamba to your configuration.nix plus a few lines of config for nix-ld. Many other python/ML projects are setup to use docker, and that's another easy option.

I don't have the time or desire to switch all my python/ML work to more conventional Nix, and haven't really had any issues so far.

[+] zoogeny|9 months ago|reply
Nix falls into the camp in my mind that includes Rust: great idea that I just don't have time for right now.

Reproducibility is the holy grail, IMO. It is so valuable that any system that actually achieves it will find some longevity and eventually be hammered into a useable form. I believed in the promise when AWS was all about amis. Then I believed in the promise with docker. It seems something like Nix is a natural next step in this evolution.

I want it to succeed enough that it gets easy enough for me to use. But for now I'll stick with macOS for my laptop and docker with alpine for my deployments.

[+] codethief|9 months ago|reply
> Reproducibility is the holy grail, IMO

> I'll stick with […] docker with alpine for my deployments

Huh. In my experience Alpine is the worst possible base image to use if you care about reproducibility.

  - The package index's URL cannot be pinned (URL expires on a regular basis)
  - The downloaded package index itself (tarball) cannot be pinned/cached, either, because old package versions (i.e. the URLs in the tarball) become unavailable after a few weeks.
Meanwhile:

https://snapshot.debian.org/

https://snapshot.ubuntu.com/

[+] bigyabai|9 months ago|reply
Clutter reduction and version-controlled build/packaging is where Nix wins big-time. With Direnv you can automatically enter a developer shell as soon as you CD into the directory, which is another helpful timesaver.
[+] peterbecich|9 months ago|reply
Agreed, and the full NixOS is unnecessary for the developer shell feature and Direnv
[+] sdsd|9 months ago|reply
I was so excited to give Nix a chance, but I'd prefer to program in Guile rather than Nix, so now I'm excited to give Guix a chance lol. Going to install it this Wednesday on new laptop, wish me luck
[+] seabombs|9 months ago|reply
I installed it a few months ago, I thought it was pretty good! I couldn't find a prebuilt package mirror in or near Australia though so it was painfully slow to install updates, and I didn't stick with it.
[+] xhevahir|9 months ago|reply
Better check to make sure your laptop's hardware, particularly WiFi, is compatible. Most aren't.
[+] blueflow|9 months ago|reply
Yes, but:

  du -sh /nix
I specifically remember the glibc 2.26/ucontext desaster that triggered an rebuild of the nix world and exhausted all disk space that i had.
[+] kenmacd|9 months ago|reply

     du -sh /nix
    187G /nix
This is with

    nix.gc = {
      automatic = true;
      dates = "weekly";
      options = "--delete-older-than 30d";
    };
Cleaning up some direnv versions and a `nix-collect-garbage --delete-older-than 5d` would bring it down to around 40G. For me this isn't _too much_ space, but it's easy for an update to download multiple gigs, so something to keep in mind I guess.

The size of the nix store has never really caused me issues, but ending up with a full `/boot` has. I now always set `boot.loader.systemd-boot.configurationLimit` to avoid these issues.

[+] atrus|9 months ago|reply
Yeah, if you only have nixos on a space constrained device (like my poor old chromebook), you're going to have a bad time.

The plus side though if you go all in is that you can build once on something more powerful and just copy the updates to the low powered stuff.

[+] bfrog|9 months ago|reply
I’ve tried a few times now, it’s great when you don’t have to actually write nix yourself. At scale though the typeless dictionary style parameter approach is so impossibly unreadable, constantly hunting down some nixos helper and its underspecified parameters is painful. Its honestly a lot of the same pain yaml has at scale. Lack of typing means more burden on me to remember everything, except nix adds to this a really tough debugging story as it’s lazy and the error messages aren’t usually that helpful.
[+] dbalatero|9 months ago|reply
I recently had to switch back from Nix, as the way it operated clashed with the corporate IT security controls on my work laptop and prevented me from using it.

I just went back to Bash and it honestly works just fine, any rough edges probably don't outweigh how inscrutable Nix tends to be: https://github.com/dbalatero/dotfiles/blob/main/apply

[+] craftkiller|9 months ago|reply
> These hashes are computed using SHA-256

Not so fast! The hash story is actually much more complex than that, as this recent article showed: https://bernsteinbear.com/blog/nix-by-hand/

Regardless, the hash function is irrelevant to end-users, I just thought it was interesting that they cooked up such a convoluted scheme.

[+] douchescript|9 months ago|reply
Nix + flakes & direnv is the perfect dev environment, run it on the Mac and everybody in team can setup any project in seconds. We also have a makefile that sets up Postgres / init,start,stop with a local file socket - so every project instance has it’s own db instance. Very jummy.

That said I wish it was easier to be able to pick a specific build of for example ruby like ruby-3.3.7-p123.