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 · 23h ago
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.
pxc · 23h ago
Flakes and the unstable branch of NixOS (the `nixos-unstable` branch of Nixpkgs) are unrelated.
Flakes is an "experimental feature" of Nix itself, but it has shipped in stable releases of Nix for years now. There was a time when you had to build an unreleased version of Nix to play with flakes but that was a long time ago.
Whether you use a rolling release for the package set, e.g., nixos-unstable or nixpkgs-unstable, is orthogonal to whether or not you use flakes.
Fwiw, I generally prefer to run the unstable branches of Nixpkgs. Occasionally you hit something you have an opportunity to fix yourself, but that's not very frequent these days, even on the unstable branches.
IshKebab · 19h ago
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.
sureglymop · 17h ago
I find this to be a real issue with environment variables.
I am trying to create a tool to help see exactly where and by which program any environment variable was set/exported since boot.
This is still in the conceptual phase but I'm looking into linux' ftrace to achieve this. Any ideas or pointers are welcome.
IshKebab · 3h ago
Yeah I think you can definitely find which process sets environment variables (I think you just need to intercept execve or whatever). The real problem is finding which processes use the environment variables. That's extremely difficult, if not impossible.
urlwolf · 1d ago
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.
sepositus · 1d ago
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.
nextos · 23h ago
I think Nix is getting an unfair reputation for being too hard. Simple things are IMHO simpler in Nix than in any other distribution, and what one needs to know to accomplish them is tiny. It has basically reduced my sysadmin maintenance tasks to zero. In case of regressions, Nix makes it trivially easy to go back in time 2 or 3 years, cherrypick some packages and install them, or change your entire desktop environment, and then go back to the previous state with no effort.
Nix is hard if you need to build something difficult to package or something that has very unusual or dirty build processes. If you need to that regularly, Nix is not worth the effort unless you are an organization that values reproducibility and is prepared to pay for its cost upfront. If these particularly messy usecases are something that you don't encounter so frequently, you can always use an escape hatch to be able to make your install impure. For instance, distrobox is quite convenient to run e.g. an Arch or Ubuntu container. In my case, this has been helpful to run Julia, whose Nix packages are quite brittle.
davidcox143 · 21h ago
I've been using Nix and NixOS since 2022. I can't imagine not using Nix at this point and agree that the reputation for "being too hard" is not quite accurate. Nix is different - that's the point.
The learning curve is a thing, although I'd argue that it's nowhere near as steep as the tools many of us use every day (C++, Rust, AWS/GCP, etc.)
Nix's "difficulty" IMO comes from defaults that are not sane and a split community. For example, if you use the official Nix installer, flakes are not enabled by default (despite being widely used [1]), but they are if you use the Determinate Systems Nix installer.
Flakes are realistically the only way to obtain the benefits that motivate learning Nix (deterministic pure builds, fine-grained control over dependencies) and are the "primary driver of Nix's adoption" [2]. AFIK there isn't a viable alternative to flakes other than maybe atoms [3], which are relatively new (like "lock files are totally hand made" new [4]). Yet, the official Nix stance on flakes is to wait... for... what?
For a day-in-the-life look at more of Nix's rough edges, I posted some rambles here [5].
My understanding of atoms compared to flakes is that they 1) add toml 2) provide a more precise way to reference remote src.
The author also claims performance benefits. I haven’t used them personally and can’t speak to their stability or ergonomics.
codethief · 7h ago
Thanks!
jrockway · 19h ago
I think the reputation is fair. Why is flakes still experimental, for example? That's a subtle bit of encouragement to do things the old way and as a result, documentation is always mixed and you end up "but how do I do that in a flake".
Something that is in theory nice is using the same packages in development and production. But "everyone" uses Mac OS for development and Linux for production, and if you want to guarantee that every developer on your team isn't recompiling Node from scratch, you want to use nixpkgs-25.05-darwin instead of nixos-25.05 on Mac OS. The result is that you aren't actually getting the same package across systems, which is rarely problematic but is something that Will Go Wrong someday. Why not keep Darwin stable in the main stable branch?
I have also found the entire system incredibly unstable during release pushes. Lots of stuff broke in 24.11 and unstable as 25.05 was being prepared (notably nodejs_20). What I learned from this experience is "don't touch package updates in May or November" which isn't amazing if you care about security updates.
So basically, Nix is incredibly rough around the edges. nixpkgs is a much better package repository than anything else I've used, but it's not perfect. It's generally more up to date than Debian unstable. It supports more platforms than Homebrew (which doesn't work on linux-aarch64, a platform I use heavily). Overall the philosophy of making each package entirely self-contained is the right approach.
NixOS is also fine, mostly... but I use Bazel to build all my personal projects. Bazel does not work well on NixOS. For some reason, nixpkgs doesn't have Bazel 8 which is the version I use (because if you don't update your project to a recent Bazel today, you'll have to do it tomorrow). If you get a NixOS-compatible bazel 8 from some random flake, you can solve that problem. But then there are a lot of assumptions the Bazel ecosystem makes, and those are unresolveable. To the Nix folks, having your build system download the official distribution of Go, verifying the sha256, and execing it to do your builds is unthinkable. Personally, I'm fine with it. The Go team knows how to release Go better than anybody. But this impedance mismatch makes it nearly impossible to have a project that builds on "normal" Linux and NixOS. You can go full Nix and get go, c++, etc. from nixpkgs, but then everyone has to have Nix before the can work on your project. I would be OK making that decision for myself (I already use Nix), but I imagine it's a hard sell if you just want to fix development at work. People would complain. People will run into problems. To some extent, this is Bazel's fault (and the ecosystem) for assuming that /bin/bash and some vaguely recent /lib64/ld-linux-x86-64.so.2 exists. NixOS says "no it doesn't unless you declare it and get it out of $PATH" but honestly which version of bash runs "exec bazel-out/program-that-was-just-built" is irrelevant in practice, so it's just an unnecessary barrier. There is an attempt at compatibility for those that don't care about versioning the version of Bash that each shell script runs (envfs, nix-ld), but at least for me, it doesn't work. All in all, the net result is that I can't actually do work on NixOS, and I can't write a flake so my home-manager configuration can install all the software I've written for myself, which is a pretty bad feeling. Building my projects is easy... "git clone git@github.com:jrockway/monorepo; cd monorepo; bazel build //jlog/cmd/jlog; cp bazel-bin/jlog/cmd/jlog/jlog_/jlog ~/bin". But it's literally impossible on NixOS simply because something in the 10,000 lines of other people's code wrote "#!/bin/bash" somewhere. That's pretty rough.
My TLDR is if you want the latest version of Git on Mac OS, linux-aarch64, and linux-x86_64, you should probably look at nixpkgs and home-manager. I like 'em. I don't think there's anything better. Everything else... it's rough. When you commit to leaning into Nix, a lot of your free time is going to disappear for a while.
nylonstrung · 1h ago
Hopefully Nix and Bazel can learn to play nice. There have been 5 talks on this in the last year alone, so I think many others are in your same boat
Why is it inevitable that you have to leave the comfortable area of "those who have done it before" though?
Most of the benefit of nix for me is maintaining a configuration for a couple computers in a way that's easy to backup, upgrade, and recover with.
sepositus · 23h ago
For reference, I use Nix to manage three different machines, always via home-manager and nix-darwin (I left NixOS awhile ago and haven't looked back). I don't think it's "inevitable" that you'll hit the difficulty wall, but certainly likely.
As an example, I was recently playing with Pyinfra which is like a pure Python version of Ansible. It turns out that one of the dependencies uses an archaic version of setuptools and the package owner had inserted some _very_ hacky code that ended up breaking on two of my systems. Now I'm relatively experienced with Nix, so it took me a few hours to track down, but it would have been days if not impossible for a beginner.
Nowadays I package brew along with my machines and as soon as something smells funky in Nix I just manage it with brew. Much more peaceful.
packetlost · 22h ago
Been there. Powered through it. It gets easier when you actually read the Nix manual.
danieldk · 11h ago
Nix Pills are probably the best way to get a deep understanding of Nix and some underpinnings of nixpkgs. I read the pills when I started using Nix in 2018 and never had much difficulty understanding the language or most of nixpkgs.
packetlost · 47m ago
The biggest thing I've hit is linking issues with Rust -sys crates (ie. C/C++ libraries wrapped). There's some very strange behavior if you include gcc and clang (for example) into the same environment.
My biggest issue with Nix tbh is it adds an annoying step to every random repo I want to clone and build.
kstenerud · 20h ago
Been there. Powered through it. Read the manuals. Stuck to it for a year before asking why I was behaving like a masochist.
Now I use Debian and LXC and docker.
exe34 · 23h ago
> Welcome to the honeymoon phase. Mine lasted about a year
Mine has been going on since 2016, what am I doing wrong?
sepositus · 23h ago
> they just don't try hard enough
The answer was in my post. Nix isn't for everyone, and that's OK.
myaccountonhn · 22h ago
I've returned and my new approach was to learn:
1. The repl for exploration
2. The language (read nix.dev)
3. Read the nixos manual
And with that it started to make sense.
exe34 · 8h ago
I've actually gone the other way - not everything is meant to be run. If it's not in the nix repos, I'll try the fhs, and if that doesn't work - well I probably don't care enough to beg it to run. For me the fact that my base installation can never break is not negotiable.
I definitely didn't learn much of nix(os|pkgs). I never bothered learning about flakes. I just have a configuration.nix and a user config.nix, and a "fhs" default.nix and that's it.
zachlatta · 1d ago
Can you link your dotfiles? I’ve been having trouble figuring out a good way to structure mine
My servers don’t have that many dotfiles because most server software can be configured in /etc (zsh, vim), while my work computers have a lot of dotfiles symlinked into ~/.config/ via Nix, e.g. VSCodium, ghostty, …
Most people prefer to Nix up their dotfiles, which provides some advantages (e.g. universal styling via Stylix), but the main drawback that I’m not buying is: I can’t share my app-specific config with non-Nix users.
Until your use case hasn't been deciphered by a Nix scribe and then you have to fight the magic.
johnisgood · 1d ago
Which makes "next to zero time wasted configuring things" false, very much so. You will have to write your own derivation(s) using Nix[1].
In any case, from the article, what does not apply to Guix, too? I am leaning towards Guix because of its language (Scheme, i.e. Lisp-y), but I wonder about the differences between the two, today (besides userbase and hype).
Agreed on Guix. Used it for a few years, absolutely loved it, excited to go back (had to move off for unimportant and unrelated reasons).
Would love to hear from someone who has used both though.
I've never seen an excellent, detailed comparison actually, as conversation on the subject tends to devolve into a "discussion" on ethics. Meaning, people who dislike GNU or GPL or Lisps or something get testy and argue uncharitably (imho, please prove me wrong, not flaming here, etc).
This is ironic, to say the least, as one of the main points of the proponents of the "anti-GNU" side tends to be how Guix is too opinionated and pushy and hard-line etc. So we've a classic upside-down situation, which is a real shame, as Guix seems to be in reality a practical project with lovely people involved that's doing very interesting work.
pxc · 23h ago
The Guix blog has really good and detailed discussions of things Guix has done differently than Nix! Posts on the choice of different abstractions for modeling services in Guix is probably a good starting point.
The UI differences are also striking right away. Guix has a more unified CLI, and the main Guix repo seems to more quickly absorb functionality that's split into various community projects in Nix.
mplanchard · 1d ago
Mainly the mindshare. Nix has a massive set of packages. You’ll have to build more derivations for guix.
pxc · 23h ago
Guix already has as many packages as Nixpkgs did back when I started using it, and like Nixpkgs, the package set is growing exponentially. What you say is true but it also seems to me like for many, Guix already provides a very useful starting point.
mplanchard · 2h ago
I hope you’re right. I love nix and NixOS, but I really don’t enjoy the nix language. A lisp would be so much more pleasant.
johnisgood · 1d ago
I assumed that, but "only" that? I genuinely wonder. I did not get around to try Nix yet.
mplanchard · 16h ago
I think it’s “only” that yeah. Both have fundamentally the same capabilities. Nixpgs may provide more out of the box library functionality than guix, I’m not sure, but as far as I know there’s nothing possible in one that isn’t possible in the other. Would be glad to be corrected by anyone with more experience, though. I’ve run NixOS for years now, but have only dabbled with guix.
bigyabai · 1d ago
I guess relentlessly dylibbed software like AppImage is the elephant in the room. Nix struggles to handle those types of programs, but they tend to work fine in Flatpak or with a special tool (eg. appimage-run or steam-run).
sshine · 21h ago
Struggle how?
There’s an entirely mechanical workflow for calling patchelf when packaging a binary that was compiled dynamically against library paths outside of the Nix store.
OscarCunningham · 23h ago
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 · 20h ago
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.
__MatrixMan__ · 19h ago
If that scratches the itch, great. Backups of /etc can't be combined in a way that lets you reliably uncombine them later though, so you're going to be limited in how modular you can make it.
layer8 · 19h ago
That’s true, though using version control with branches and merges can get you pretty far.
OscarCunningham · 19h ago
I believe 'dpkg --get-selections' lists all packages, not just the ones the user installed. So if I installed some package foo that had a dependency bar, this method would have me carrying around bar even if foo updated to stop depending on it.
layer8 · 19h ago
You are right. In that case, apt-clone is better, though not universally available.
pabs3 · 5h ago
The Debian cruft-ng package, plus package list diffs, can identify problematic state you have added to the system.
Altern4tiveAcc · 22h ago
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 · 18h ago
> No, most people won't be happy that Nix breaks dynamic linking.
True. In my case I just enabled nix-ld[0,1] and now everything works flawlessly.
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.)
johntash · 18h ago
Are you using NixOS, or are you using Nix + home-manager or something like that to manage your user's stuff?
codethief · 16h ago
Just NixOS. When building the VM / live CD I copy my dotfiles into the Nix store and then during first boot-up I copy them into my home dir and set up symlinks.
The main reason I decided against home-manager was that it makes my simple symlink setup (~/.foo -> ~/.dotfiles/foo) virtually impossible: Symlinks will always point to the read-only Nix store in one way or another. See https://github.com/nix-community/home-manager/issues/3514 or one of the countless other tickets on the topic. Through this episode I also learned that home-manager isn't exactly well-documented, either, and also quite opinionated. (Which, to be fair, is not a bad thing – if it works for you, it probably works great.)
Finally, not using home-manager was also a risk management decision in that it's probably best to not go all-in on Nix, NixOS, home-manager etc. all at once. Start with the simplest possible config that gets you running, then iterate.
Modified3019 · 19h ago
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.
danieldk · 11h ago
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.
pxc · 4h ago
I want to second this experience. I've never actually submitted my contributions upstream for other distros, but I've maintained repositories for personal use for Ubuntu, openSUSE, Arch, Gentoo, CentOS and Fedora.
Writing a new package from scratch based on Nixpkgs is far easier than for other distros, and easy packaging tasks are much easier with Nixpkgs than with other distributions.
(It's also much easier to distribute packages without standing up new infrastructure with Nix, since it's source-based and will fall back to source-based builds if you have no established mechanism for distributing binaries.)
weinzierl · 1d ago
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__ · 1d ago
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.
weinzierl · 22h ago
Thanks for that detailed argument, especially for pointing out the three necessary components.
I agree even with the following paragraph in principle:
"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."
For me it is not so much about what the council of elders says, but more about when FAANG and Co. are OK to run a binary I think needn't worry about the rest.
Or to think this further, they should care more about Nix than I should.
pabs3 · 5h ago
These are the solutions to the three components:
> - is this actually the binary that comes from that code?
Reproducible Builds that are also Bootstrappable Builds, starting from a minimal auditable machine code seed.
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:
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/
subsection1h · 20h ago
> All the package definitions [...] are "code reviewed". [...] with maybe some reviewed patches to get it to work in Nix's environment.
In order for people to review Nix package definitions and patches, do they need to have their keys signed by other Nix contributors they meet in person like Debian contributors do?
No. People who have contributed a lot can get nominated and if no one raises objections, they typically get the commit bit.
It is less than ideal. On the other hand, self-reviews/merges are frowned upon, so there is normally an extra set of eyeballs that checks changes. Besides that, nixpkgs has a really large number of non-committer contributors. Packages often get touched by multiple if not tens of people. So, even though Linus' law typically doesn't hold up, I do think it holds up pretty well for nixpkgs.
mplanchard · 1d ago
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.
cjbgkagh · 22h ago
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.
bigyabai · 1d ago
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.
remram · 23h ago
FYI by calling it "job security" you imply that this nix caching approach is unmaintainable.
pxc · 23h ago
He made himself useful by practicing an uncommon skill, so I understand why it was put that way.
But Nix is plenty learnable and Nix hires are possible, so I see what you mean.
bigyabai · 21h ago
It's implied because it's true. Throw away the content-adressable cache index and you're back to 2 hour development velocity, so the Nix guy probably gave himself a decade and a half of runway for a workload that mostly amounts to periodically running `nix flake update` and shuffling around version hashes.
We already saw this same trend happen where "the CMake guy" or "the Xcode guy" gets wheeled in to solve their domain-specific issue in large enough orgs. I was impressed by this guy's initiative to carve out an equally indispensable niche.
pxc · 3h ago
In truth, the "job security" thing is often as much a matter of personality as it is explicit strategy. The "XYZ guy" often becomes that person simply by being someone who is stubborn enough to tackle integration problems most people would rather avoid, and by being willing to deeply embrace "RTFM".
To say they've established "job security" can sometimes seem like a cynical read on their roles, but I think it's always good for teams to have a few devs with this sort of personality.
kombine · 23h ago
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 · 23h ago
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 · 1d ago
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??
__MatrixMan__ · 23h ago
For each project, configure a nix devshell to include the appropriate linters etc for that project. Then configure direnv to activate the nix devshell when you cd into the project directory. Then launch your editor from that shell. Since the editor's parent process is the devshell, its PATH var points to that project's dependencies.
Or at least that's how I do it. That will make `ruff` or `pyright-langserver` point to whichever version of the tool is bound to that project. So when I run `nix flake update` it updates the tools for only that project and I don't get any crosstalk between projects.
As for whether a given linter or language server should be configured for that project, helix looks for .helix/languages.toml in the CWD to decide which ones to load, so that bit of config I handle independently from nix, I just add that file to the repo. Presumably emacs has something similar.
So to answer your question: you only get a project-specific version of emacs if you add emacs to the project's devshell. Otherwise whatever was already on your PATH will be used.
My Emacs then sets up an LSP per project, and just picks up the correct LSP implementation by PATH.
No per-project Emacs madness. (Though I guess you could do that if you wanted by including copies of Emacs with all the appropriate packages in your development environments.)
mystifyingpoi · 22h ago
I have never tried Nix, but read about it a lot, and I agree that this part is most of the time completely glossed over in tutorials. I get that nix-shell is cool, and I can get the shell with everything configured to run, let's say, Python with specific deps, very easily - but... then what? Can I run, let's say, IDEA or vscode from there and get all the PATH stuff right? Or does it require extra magic? Not everyone lives and breathes in terminal (even though I mostly do).
pxc · 3h ago
> Can I run, let's say, IDEA or vscode from there and get all the PATH stuff right?
Yes.
But if you use an editor for many projects at once, it'll work better if different projects can have different PATHs set, in which case you can use direnv + an appropriate direnv plugin for your editor. That way you don't have to worry about launching your editor from inside nix-shell or whatever.
IIRC IDEA is still defective in this way, not allowing per-project environment variables, but Emacs, Vim/Neovim, and VSCode all handle this nicely.
mplanchard · 1d ago
Easiest thing is to use direnv to load your nix environment (which is just ‘use nix’ or ‘use flake’, support is builtin to direnv), so that all the nix stuff is first in PATH. There are packages to help with this for emacs, like envrc-mode and direnv-mode, that will load the envrc file whenever you’re visiting a file in the project. Then, whenever emacs runs some external command, it’ll pick up the right one.
There are similar plugins for vscode, vim, etc
strobe · 21h ago
In most cases is enough to have emacs installed as part of OS with all required general cli tools and then open project specific shell with all project dev dependencies like compilers and libs.
However is some cases when it could be little more tricky, for instance I'm using LSP for Scala (https://scalameta.org/metals/) which on start trying to automatically detect JDK version for project from environment. So if my project depends on JDK 11 it might required for me manually start LSP from nix-shell to force it use right JVM version.
With Rust is in someway similar, I need to bring some shell with 'rust up' setup so it could install everything for rust-analyzer then emacs can use it.
Regardless emacs itself is few options to manage emacs packages in nix way but for me it not really gives anything so I just use it as on any other OS.
bigyabai · 1d ago
The "correct way" is flakes, but I don't know if it would cover every edge case. I don't use emacs, but I'd assume you'd arrange it a bit like this:
- Install nixpkgs emacs or emacs distribution to your user profile so it links into every shell you open.
- Each project (or group of projects) gets a Nix flake with a derivation specifying which dependencies or LSP packages are needed.
When a devshell is spun up, you should have the nixpkgs version of Emacs with your system-wide config and project-specific modifications, handled via version-control. It is a hassle, but in my experience the ROI is very worthwhile. YMMV.
krapht · 1d ago
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 · 1d ago
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 · 22h ago
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.
sdsd · 1d ago
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 · 18h ago
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 · 20h ago
Better check to make sure your laptop's hardware, particularly WiFi, is compatible. Most aren't.
seabombs · 18h ago
You can install/run guix using a nonfree kernel to get around that.
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 · 1d ago
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.
CuriousRose · 6h ago
For someone wanting to use nix for the premise of the article (dev environment management), I'd encourage you to checkout Coder[0] which I'm self-hosting personally for my company, but will prove useful once I hire.
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.
Regardless, the hash function is irrelevant to end-users, I just thought it was interesting that they cooked up such a convoluted scheme.
dbalatero · 1d ago
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.
Nix is great but the user interface is ugly and cryptic.
Debugging dependency issues (what depends on this package of particular hash), installing a particular version of a package is just more trouble than something you would get from the likes of npm or cargo.
Would I use nix for my servers? Yes.
Would I also use nix personally to keep my systems in sync? Yes.
Will I recommend nix to others? Absolutely not.
pjmlp · 23h ago
For me it is another Gentoo.
I had my time trying every new distro that would be popping up on Linux related magazines CD/DVDs up to the mid-2000's (they still do in some European countries), unless it comes on a laptop I can get at the mall computer store, or some customer imposes it on our delivery contract, not really something I want to give a chance to.
pxc · 23h ago
> I had my time trying every new distro that would be popping up on Linux related magazines CD/DVDs up to the mid-2000's
Me, too! That was a blessed part of my childhood and adolescence.
You're not entirely wrong about the comparison to Gentoo, but I do think NixOS is more practical than Gentoo.
codethief · 18h ago
To me Gentoo vs. NixOS is like night and day. Building an entire system from scratch only takes you a few minutes in Nix, whereas with Gentoo you'll likely still be compiling X tomorrow night.
watusername · 23h ago
> some customer imposes it on our delivery contract
It's happening: Companies are adopting Nix [0] and you may see such requirement come up some time.
In the bubble I live on, classical VMs have become the exception nowadays, containers and serverless deployments are the rule now.
I am yet to see any classical VM deployment isn't one variation of Debian, Ubuntu, Red-Hat, SuSE.
Note how that list has a certain startup feeling to the company list, not boring big corp.
watusername · 22h ago
> In the bubble I live on, classical VMs have become the exception nowadays, containers and serverless deployments are the rule now.
Nix does not require NixOS, and I would even wager that in corporate dev environments it's most often used in a standalone manner.
You can install Nix on Debian/Ubuntu/RedHat, get a reproducible local dev environment and build reproducible OCI images that can be deployed to K8S/Cloud Run/Fargate/etc [0], without ever touching NixOS.
Yeah, but I would I want to advocate that to customer IT teams that never saw it on their lives, wish them good luck and jump ship?
stackskipton · 22h ago
Even if classical VM deployment, I still see a ton of containers. Like our database servers Ansible playbook which run Ubuntu are "Setup OS, mount disks, install docker apt repos, install stable docker, run container.
So Nix would let us avoid the Ansible playbook by just installing the Nix file but Ansible playbook is extremely rock solid so it feels like a problem we don't have. Also, we do pay for support for Cassandra to someone and while they officially would support us running on Nix, it's clear their support technicians are much more comfortable with RH or Debian based systems.
zylent · 22h ago
Arista, D.E. Shaw, Google are boring big corp
Several of those companies (replit) are building their business on nix.
With nix, even containers are optional.
pjmlp · 22h ago
From those I only know Google and replit, which is still kind of unicorn, and most businesses will never be 1% of Google size.
zylent · 20h ago
The others are big, trust me.
My point was that some businesses are tying their destiny to nix - in my experience this is a sign that an open-source project will gain corporate benefactors keeping it afloat + making it safer for others to adopt.
PaulDavisThe1st · 21h ago
What problem(s) does Nix solve that macOS's .app format does not? For that matter, that ad-hoc Linux packaging solutions involving LD_LIBRARY_PATH and included dependencies?
Put differently, doesn't the fundamental complexity of Nix come down to the combination of (a) "every app should get its own dependencies" and (b) "don't include dependencies with each app" ?
spijdar · 21h ago
Building those applications consistently and reliably, e.g. being able to hop on a random Linux box and be able to build and deploy an application without thinking about where to fetch copies of all the dependencies. Nix’s raison d’etre is really to make developer lives easier, IMO.
I don’t use Nix, but I’ve played with other Linux package managers enough to understand the desire for something better, and something that’s actually predictable, especially (emphasis here!) when mixing/matching arbitrary versions of dependencies. I used Gentoo/Gentoo-derivates for several years and it (building random packages with == specific versions) is a sticky problem when using a traditional build system.
Of course, once the packages are built then you can do whatever hacks to bundle the dependencies with it. But the hard part is building them in a consistent, “reproducible” way.
PaulDavisThe1st · 19h ago
"build and deploy" are two entirely different tasks.
Both the macOS .app design, and various ad-hoc Linux packaging strategies deal with the deployment step in a relatively trivial, extremely non-invasive way.
The build step is something else entirely, and while I can imagine that for some projects what Nix offers has much value, for others the problem is solved by a permanently deployed build stack (or stacks) whose specificity goes beyond anything that a distro-managed system could offer.
__MatrixMan__ · 18h ago
I think you're right that it's the build step where nix provides value. It's about replacing:
> a permanently deployed build stack (or stacks)
with a consistently deployable build stack. So if you want to distribute a .app package, you could use nix to build it, and then people could download it and install/configure it according to some different scheme.
But if it's trivial to reliably instantiate the build stack, why not just ship that instead and dispense with the special format? Then nobody has to wonder if you slipped some malware in the package before you distributed it.
The idea behind NixOS is that since we must precisely define our build stack anyway, why not use the same technology to define the rest of our OS. Maybe that's overkill for some, but it sure is handy that there are NixOS users out there so when I want to use something from nixpkgs when defining my dev environment on MacOS it already has the kinks worked out.
As for
> ...whose specificity goes beyond anything that a distro-managed system could offer.
My feeling is that most nix code is not distro managed but rather written by individual project maintainers. We only bother contributing something to nixpkgs if we think it's widely applicable.
PaulDavisThe1st · 16h ago
> with a consistently deployable build stack. So if you want to distribute a .app package, you could use nix to build it, and then people could download it and install/configure it according to some different scheme.
> But if it's trivial to reliably instantiate the build stack, why not just ship that instead and dispense with the special format? Then nobody has to wonder if you slipped some malware in the package before you distributed it.
This suggests to me that either you don't know how .app packaging works on macOS (or various ad-hoc packaging on Linux, such as Firefox or Ardour), or you're making a point that I'm missing.
The whole point of these non-Nix systems is precisely that you just package up bits of the build stack into the thing you distribute, and you reduce or eliminate system dependencies other than such basics as the system C library or X11.
__MatrixMan__ · 15h ago
I had misunderstood what a .app package was, thanks for clarifying. So do people package things like linters and language servers into the .app also? Like, is it everything I'd need to work on the app, or is just everything I'd need to run the app?
PaulDavisThe1st · 15h ago
Everything needed to run the application.
douchescript · 22h ago
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.
xena · 1d ago
Honestly it's not been worth my time. I spent more time shoving things into Nix than I did shipping.
benreesman · 7h ago
Nix is still waiting for its GitHub moment. It's possible to live a strictly better life (as an individual or company) via Nix and NixOS but there's still a ton of lore and inside baseball that requires a pressing need to justify learning it all. If there's a serious Nix person in your company or friend group it's time, otherwise be ready for a learning curve that's only worth it if you have one of the problems it solves (if Docker is starting to be a weird init system or devs are finding excuses to go around it). It's the choice of people who can't compromise on anything (Anduril, more and more trading shops, shit like that).
Nix is in a bit of a split/argument/fork-prone thing at the moment but it looks like this will settle into a practical/purist thing where everyone can be happy, so go in knowing which crowd is your people.
I'm not a purist so listen to one of them if you are. That said:
- flakes aren't optional or experimental, they're the default, its a small clique holding it up for years and its getting forked around by everyone serious
- flake parts is looking like a lock for the de facto flake standard, something else might come along but the leet stuff is congregating around it
- Cachix devenv is a good gateway drug: its better than Docker and easier to graduate from when it gets serious on that component
- nix-ld and FHS envs aren't a sin, they fix most all the friction bilugs and should be the default design, I overlay the shebang thing and all the unfree restrictions and all of it: the incompatible by design people are aging out, this will all work flawlessly in a year or two and you can do it today but its inside baseball
If you need to support Mac and Linux without the limitations of a strict all-OCI flow it's your best option, if you need a chance in hell against serious supply-chain attacks its your best starting point. If you need to run on a mix of metal and cloud and/or double-virtualizing is an issue its The Way.
The best super accessible resource to go from zero to "holy shit computers can do that" is vimjoyer's YouTube.
Use sops.nix and your secrets management is solved. Also by Mic92 is nixos-generators, that is basically infinitely portable to anything. juspay's GitHub, srid's GitHub, pretty much all the nixos-asia stuff is galaxy brain next level. It all works great on MacOS if you're not over it yet with the telemetry.
(sidebar: telemetry is your biggest computer problem now and your phone addiction is part of the telemetry deal. Linux and Graphene and NextDNS and Proton and stuff are worth it even for Grandma finally. I'm glad the purists do their thing, its an act of service).
nylonstrung · 46m ago
Couldn't have said it better, this is a perfect description
> It's the choice of people who can't compromise on anything (Anduril, more and more trading shops, shit like that).
This is crucial- Nix has interhent advantages in certain industries where it IS genuinely easier than any alternatives. We're gonna see adoption start there and disseminate to general tech companies in a more consumerized form IMO
bigyabai · 1d ago
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 · 1d ago
Agreed, and the full NixOS is unnecessary for the developer shell feature and Direnv
yungporko · 1d ago
interesting that the author blames "the modern developer tooling ecosystem" for the issue of not being able to reproduce builds, it's still a problem of course but in my experience it was way worse in the past, with most ecosystems i've used adopting some kind of passable package manager now.
roydivision · 10h ago
> More importantly, Docker containers themselves aren’t reproducible—running apt-get update or pip install requests at different times can yield different results, even with the same Dockerfile.
apt-get install <package name>=<version>
> And frankly, no one really needs Kubernetes, they just have it because everyone and their grandma has it. I digress, that’s a topic for another day.
Oh grow up, ffs.
yakshaving_jgt · 1d ago
The time to “give Nix a chance” was already years ago.
mar0ux · 13h ago
p oo de n nn d but vvjjfc. A b
Tractor8626 · 21h ago
Wow.
1) you can python environment with dependencies!
(can do that without nix)
2) you can pin dependencies by hash!
(can be done with any tool mentioned in article: docker, pip, npm etc)
If you can't make reproducible dev environment in 2025 - it is 100% skill issue.
__MatrixMan__ · 18h ago
Having to think about docker's hashing/caching scheme and also pip's and also npm's and to apply them each separately in CI and in a local environment and in dev/stage/prod... for a large repo that's a lot of work. Easy to overlook whichever one you're less concerned about at the time and put the repo in some kind of inconsistent state where something works here but not there.
There's a lot to be said for having a single lockfile for all of them.
Tractor8626 · 7h ago
No. It is not nearly as hard as you make it sound.
If I had to work with such mess of a project - I wouldnt bother with package managers at all. I just download and commit all dependencies to repo.
If dependencies are not supposed to change anyway - what is the point of downloading them from all over internet each time?
corndoge · 21h ago
For 1), how?
I'm specifically interested in how you handle packages that use C extensions that link system libraries.
Tractor8626 · 20h ago
In such cases I use either docker or mmdebstrap.
corndoge · 11h ago
Nix would work too, and that fact touches on one of the main advantages of Nix - it solves the problem at a low enough level that it works in all cases.
Tractor8626 · 7h ago
There is hidden assumption what using one tool for everything makes things easier.
Does it though? If using one tool is harder than using several - there is no advantage here.
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.
I've moved to Atomic desktops and can't name anything I am missing. For dev stuff there are containers.
Flakes is an "experimental feature" of Nix itself, but it has shipped in stable releases of Nix for years now. There was a time when you had to build an unreleased version of Nix to play with flakes but that was a long time ago.
Whether you use a rolling release for the package set, e.g., nixos-unstable or nixpkgs-unstable, is orthogonal to whether or not you use flakes.
Fwiw, I generally prefer to run the unstable branches of Nixpkgs. Occasionally you hit something you have an opportunity to fix yourself, but that's not very frequent these days, even on the unstable branches.
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.
I am trying to create a tool to help see exactly where and by which program any environment variable was set/exported since boot.
This is still in the conceptual phase but I'm looking into linux' ftrace to achieve this. Any ideas or pointers are welcome.
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.
Nix is hard if you need to build something difficult to package or something that has very unusual or dirty build processes. If you need to that regularly, Nix is not worth the effort unless you are an organization that values reproducibility and is prepared to pay for its cost upfront. If these particularly messy usecases are something that you don't encounter so frequently, you can always use an escape hatch to be able to make your install impure. For instance, distrobox is quite convenient to run e.g. an Arch or Ubuntu container. In my case, this has been helpful to run Julia, whose Nix packages are quite brittle.
The learning curve is a thing, although I'd argue that it's nowhere near as steep as the tools many of us use every day (C++, Rust, AWS/GCP, etc.)
Nix's "difficulty" IMO comes from defaults that are not sane and a split community. For example, if you use the official Nix installer, flakes are not enabled by default (despite being widely used [1]), but they are if you use the Determinate Systems Nix installer.
Flakes are realistically the only way to obtain the benefits that motivate learning Nix (deterministic pure builds, fine-grained control over dependencies) and are the "primary driver of Nix's adoption" [2]. AFIK there isn't a viable alternative to flakes other than maybe atoms [3], which are relatively new (like "lock files are totally hand made" new [4]). Yet, the official Nix stance on flakes is to wait... for... what?
For a day-in-the-life look at more of Nix's rough edges, I posted some rambles here [5].
[1] https://x.com/d4r5c2/status/1896415101386928539 [2] https://x.com/grhmc/status/1896551138104844389 [3] https://x.com/nrdexp/status/1925892763301695978 [4] https://x.com/nrdexp/status/1925707692447871283 [5] https://youtu.be/TwVamLq5OHY
IMO 80% of Nix's shortcomings are due to 20 years worth of tech debt that we're all very conscious of
By 2030 all the rust rewrites and new tooling will have finally saved us from it
They also link this very lengthy blog post:
https://nrd.sh/blog/atom-anatomy/
My understanding of atoms compared to flakes is that they 1) add toml 2) provide a more precise way to reference remote src.
The author also claims performance benefits. I haven’t used them personally and can’t speak to their stability or ergonomics.
Something that is in theory nice is using the same packages in development and production. But "everyone" uses Mac OS for development and Linux for production, and if you want to guarantee that every developer on your team isn't recompiling Node from scratch, you want to use nixpkgs-25.05-darwin instead of nixos-25.05 on Mac OS. The result is that you aren't actually getting the same package across systems, which is rarely problematic but is something that Will Go Wrong someday. Why not keep Darwin stable in the main stable branch?
I have also found the entire system incredibly unstable during release pushes. Lots of stuff broke in 24.11 and unstable as 25.05 was being prepared (notably nodejs_20). What I learned from this experience is "don't touch package updates in May or November" which isn't amazing if you care about security updates.
So basically, Nix is incredibly rough around the edges. nixpkgs is a much better package repository than anything else I've used, but it's not perfect. It's generally more up to date than Debian unstable. It supports more platforms than Homebrew (which doesn't work on linux-aarch64, a platform I use heavily). Overall the philosophy of making each package entirely self-contained is the right approach.
NixOS is also fine, mostly... but I use Bazel to build all my personal projects. Bazel does not work well on NixOS. For some reason, nixpkgs doesn't have Bazel 8 which is the version I use (because if you don't update your project to a recent Bazel today, you'll have to do it tomorrow). If you get a NixOS-compatible bazel 8 from some random flake, you can solve that problem. But then there are a lot of assumptions the Bazel ecosystem makes, and those are unresolveable. To the Nix folks, having your build system download the official distribution of Go, verifying the sha256, and execing it to do your builds is unthinkable. Personally, I'm fine with it. The Go team knows how to release Go better than anybody. But this impedance mismatch makes it nearly impossible to have a project that builds on "normal" Linux and NixOS. You can go full Nix and get go, c++, etc. from nixpkgs, but then everyone has to have Nix before the can work on your project. I would be OK making that decision for myself (I already use Nix), but I imagine it's a hard sell if you just want to fix development at work. People would complain. People will run into problems. To some extent, this is Bazel's fault (and the ecosystem) for assuming that /bin/bash and some vaguely recent /lib64/ld-linux-x86-64.so.2 exists. NixOS says "no it doesn't unless you declare it and get it out of $PATH" but honestly which version of bash runs "exec bazel-out/program-that-was-just-built" is irrelevant in practice, so it's just an unnecessary barrier. There is an attempt at compatibility for those that don't care about versioning the version of Bash that each shell script runs (envfs, nix-ld), but at least for me, it doesn't work. All in all, the net result is that I can't actually do work on NixOS, and I can't write a flake so my home-manager configuration can install all the software I've written for myself, which is a pretty bad feeling. Building my projects is easy... "git clone git@github.com:jrockway/monorepo; cd monorepo; bazel build //jlog/cmd/jlog; cp bazel-bin/jlog/cmd/jlog/jlog_/jlog ~/bin". But it's literally impossible on NixOS simply because something in the 10,000 lines of other people's code wrote "#!/bin/bash" somewhere. That's pretty rough.
My TLDR is if you want the latest version of Git on Mac OS, linux-aarch64, and linux-x86_64, you should probably look at nixpkgs and home-manager. I like 'em. I don't think there's anything better. Everything else... it's rough. When you commit to leaning into Nix, a lot of your free time is going to disappear for a while.
https://youtu.be/2wI5J8XYxM8?si=HS0YKewPz-Mmhptn
https://youtu.be/6xWr8f2RhX0?si=sNjkJ-rwLfTI97AP
https://youtu.be/FoSCSQO5xhI?si=pHmZJjKS-mX87iyn
https://youtu.be/6qOoOsjmyZ0?si=sVppXxb1E3ml7TBk
https://youtu.be/s801fgQOGnw?si=E--1aVJyUDjjOFWW
Most of the benefit of nix for me is maintaining a configuration for a couple computers in a way that's easy to backup, upgrade, and recover with.
As an example, I was recently playing with Pyinfra which is like a pure Python version of Ansible. It turns out that one of the dependencies uses an archaic version of setuptools and the package owner had inserted some _very_ hacky code that ended up breaking on two of my systems. Now I'm relatively experienced with Nix, so it took me a few hours to track down, but it would have been days if not impossible for a beginner.
Nowadays I package brew along with my machines and as soon as something smells funky in Nix I just manage it with brew. Much more peaceful.
My biggest issue with Nix tbh is it adds an annoying step to every random repo I want to clone and build.
Now I use Debian and LXC and docker.
Mine has been going on since 2016, what am I doing wrong?
The answer was in my post. Nix isn't for everyone, and that's OK.
1. The repl for exploration 2. The language (read nix.dev) 3. Read the nixos manual
And with that it started to make sense.
I definitely didn't learn much of nix(os|pkgs). I never bothered learning about flakes. I just have a configuration.nix and a user config.nix, and a "fhs" default.nix and that's it.
Here’s a very small example:
https://github.com/sshine/nix/blob/main/shared/home-manager....
My servers don’t have that many dotfiles because most server software can be configured in /etc (zsh, vim), while my work computers have a lot of dotfiles symlinked into ~/.config/ via Nix, e.g. VSCodium, ghostty, …
Most people prefer to Nix up their dotfiles, which provides some advantages (e.g. universal styling via Stylix), but the main drawback that I’m not buying is: I can’t share my app-specific config with non-Nix users.
But if you’re looking for a cheaper (in terms of complexity) dotfiles manager: https://github.com/yarlson/lnk
In any case, from the article, what does not apply to Guix, too? I am leaning towards Guix because of its language (Scheme, i.e. Lisp-y), but I wonder about the differences between the two, today (besides userbase and hype).
[1] https://nix.dev/tutorials/nix-language.html
Would love to hear from someone who has used both though.
I've never seen an excellent, detailed comparison actually, as conversation on the subject tends to devolve into a "discussion" on ethics. Meaning, people who dislike GNU or GPL or Lisps or something get testy and argue uncharitably (imho, please prove me wrong, not flaming here, etc).
This is ironic, to say the least, as one of the main points of the proponents of the "anti-GNU" side tends to be how Guix is too opinionated and pushy and hard-line etc. So we've a classic upside-down situation, which is a real shame, as Guix seems to be in reality a practical project with lovely people involved that's doing very interesting work.
The UI differences are also striking right away. Guix has a more unified CLI, and the main Guix repo seems to more quickly absorb functionality that's split into various community projects in Nix.
There’s an entirely mechanical workflow for calling patchelf when packaging a binary that was compiled dynamically against library paths outside of the Nix store.
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.
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.
True. In my case I just enabled nix-ld[0,1] and now everything works flawlessly.
[0]: https://github.com/nix-community/nix-ld
[1]: https://wiki.nixos.org/wiki/Nix-ld
I wish Nix-ld was just bundled into Nix
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.)
The main reason I decided against home-manager was that it makes my simple symlink setup (~/.foo -> ~/.dotfiles/foo) virtually impossible: Symlinks will always point to the read-only Nix store in one way or another. See https://github.com/nix-community/home-manager/issues/3514 or one of the countless other tickets on the topic. Through this episode I also learned that home-manager isn't exactly well-documented, either, and also quite opinionated. (Which, to be fair, is not a bad thing – if it works for you, it probably works great.)
Finally, not using home-manager was also a risk management decision in that it's probably best to not go all-in on Nix, NixOS, home-manager etc. all at once. Start with the simplest possible config that gets you running, then iterate.
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.
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.
Writing a new package from scratch based on Nixpkgs is far easier than for other distros, and easy packaging tasks are much easier with Nixpkgs than with other distributions.
(It's also much easier to distribute packages without standing up new infrastructure with Nix, since it's source-based and will fall back to source-based builds if you have no established mechanism for distributing binaries.)
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.
- 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.
I agree even with the following paragraph in principle:
"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."
For me it is not so much about what the council of elders says, but more about when FAANG and Co. are OK to run a binary I think needn't worry about the rest. Or to think this further, they should care more about Nix than I should.
> - is this actually the binary that comes from that code?
Reproducible Builds that are also Bootstrappable Builds, starting from a minimal auditable machine code seed.
https://reproducible-builds.org/ https://bootstrappable.org/ https://lwn.net/Articles/983340/ https://stagex.tools/
> - is that code trustworthy?
Socially distributed code auditing:
https://github.com/crev-dev/
> - is this binary trustworthy?
The other two combined should provide this.
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/
In order for people to review Nix package definitions and patches, do they need to have their keys signed by other Nix contributors they meet in person like Debian contributors do?
https://www.debian.org/events/keysigning
It is less than ideal. On the other hand, self-reviews/merges are frowned upon, so there is normally an extra set of eyeballs that checks changes. Besides that, nixpkgs has a really large number of non-committer contributors. Packages often get touched by multiple if not tens of people. So, even though Linus' law typically doesn't hold up, I do think it holds up pretty well for nixpkgs.
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.
But Nix is plenty learnable and Nix hires are possible, so I see what you mean.
We already saw this same trend happen where "the CMake guy" or "the Xcode guy" gets wheeled in to solve their domain-specific issue in large enough orgs. I was impressed by this guy's initiative to carve out an equally indispensable niche.
To say they've established "job security" can sometimes seem like a cynical read on their roles, but I think it's always good for teams to have a few devs with this sort of personality.
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.
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??
Or at least that's how I do it. That will make `ruff` or `pyright-langserver` point to whichever version of the tool is bound to that project. So when I run `nix flake update` it updates the tools for only that project and I don't get any crosstalk between projects.
As for whether a given linter or language server should be configured for that project, helix looks for .helix/languages.toml in the CWD to decide which ones to load, so that bit of config I handle independently from nix, I just add that file to the repo. Presumably emacs has something similar.
So to answer your question: you only get a project-specific version of emacs if you add emacs to the project's devshell. Otherwise whatever was already on your PATH will be used.
My Emacs then sets up an LSP per project, and just picks up the correct LSP implementation by PATH.
No per-project Emacs madness. (Though I guess you could do that if you wanted by including copies of Emacs with all the appropriate packages in your development environments.)
Yes.
But if you use an editor for many projects at once, it'll work better if different projects can have different PATHs set, in which case you can use direnv + an appropriate direnv plugin for your editor. That way you don't have to worry about launching your editor from inside nix-shell or whatever.
IIRC IDEA is still defective in this way, not allowing per-project environment variables, but Emacs, Vim/Neovim, and VSCode all handle this nicely.
There are similar plugins for vscode, vim, etc
However is some cases when it could be little more tricky, for instance I'm using LSP for Scala (https://scalameta.org/metals/) which on start trying to automatically detect JDK version for project from environment. So if my project depends on JDK 11 it might required for me manually start LSP from nix-shell to force it use right JVM version.
With Rust is in someway similar, I need to bring some shell with 'rust up' setup so it could install everything for rust-analyzer then emacs can use it.
Regardless emacs itself is few options to manage emacs packages in nix way but for me it not really gives anything so I just use it as on any other OS.
- Install nixpkgs emacs or emacs distribution to your user profile so it links into every shell you open.
- Configure system-wide settings with the default emacs config, or with home-manager (https://mynixos.com/home-manager/options/programs.emacs)
- Each project (or group of projects) gets a Nix flake with a derivation specifying which dependencies or LSP packages are needed.
When a devshell is spun up, you should have the nixpkgs version of Emacs with your system-wide config and project-specific modifications, handled via version-control. It is a hassle, but in my experience the ROI is very worthwhile. YMMV.
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.
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.
https://wiki.systemcrafters.net/guix/nonguix-installation-gu...
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.
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.
[0]: https://coder.com
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.
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.
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
Would I use nix for my servers? Yes. Would I also use nix personally to keep my systems in sync? Yes. Will I recommend nix to others? Absolutely not.
I had my time trying every new distro that would be popping up on Linux related magazines CD/DVDs up to the mid-2000's (they still do in some European countries), unless it comes on a laptop I can get at the mall computer store, or some customer imposes it on our delivery contract, not really something I want to give a chance to.
Me, too! That was a blessed part of my childhood and adolescence.
You're not entirely wrong about the comparison to Gentoo, but I do think NixOS is more practical than Gentoo.
It's happening: Companies are adopting Nix [0] and you may see such requirement come up some time.
[0]: https://github.com/ad-si/nix-companies
I am yet to see any classical VM deployment isn't one variation of Debian, Ubuntu, Red-Hat, SuSE.
Note how that list has a certain startup feeling to the company list, not boring big corp.
Nix does not require NixOS, and I would even wager that in corporate dev environments it's most often used in a standalone manner.
You can install Nix on Debian/Ubuntu/RedHat, get a reproducible local dev environment and build reproducible OCI images that can be deployed to K8S/Cloud Run/Fargate/etc [0], without ever touching NixOS.
[0]: https://nix.dev/tutorials/nixos/building-and-running-docker-...
So Nix would let us avoid the Ansible playbook by just installing the Nix file but Ansible playbook is extremely rock solid so it feels like a problem we don't have. Also, we do pay for support for Cassandra to someone and while they officially would support us running on Nix, it's clear their support technicians are much more comfortable with RH or Debian based systems.
Several of those companies (replit) are building their business on nix.
With nix, even containers are optional.
My point was that some businesses are tying their destiny to nix - in my experience this is a sign that an open-source project will gain corporate benefactors keeping it afloat + making it safer for others to adopt.
Put differently, doesn't the fundamental complexity of Nix come down to the combination of (a) "every app should get its own dependencies" and (b) "don't include dependencies with each app" ?
I don’t use Nix, but I’ve played with other Linux package managers enough to understand the desire for something better, and something that’s actually predictable, especially (emphasis here!) when mixing/matching arbitrary versions of dependencies. I used Gentoo/Gentoo-derivates for several years and it (building random packages with == specific versions) is a sticky problem when using a traditional build system.
Of course, once the packages are built then you can do whatever hacks to bundle the dependencies with it. But the hard part is building them in a consistent, “reproducible” way.
Both the macOS .app design, and various ad-hoc Linux packaging strategies deal with the deployment step in a relatively trivial, extremely non-invasive way.
The build step is something else entirely, and while I can imagine that for some projects what Nix offers has much value, for others the problem is solved by a permanently deployed build stack (or stacks) whose specificity goes beyond anything that a distro-managed system could offer.
> a permanently deployed build stack (or stacks)
with a consistently deployable build stack. So if you want to distribute a .app package, you could use nix to build it, and then people could download it and install/configure it according to some different scheme.
But if it's trivial to reliably instantiate the build stack, why not just ship that instead and dispense with the special format? Then nobody has to wonder if you slipped some malware in the package before you distributed it.
The idea behind NixOS is that since we must precisely define our build stack anyway, why not use the same technology to define the rest of our OS. Maybe that's overkill for some, but it sure is handy that there are NixOS users out there so when I want to use something from nixpkgs when defining my dev environment on MacOS it already has the kinks worked out.
As for
> ...whose specificity goes beyond anything that a distro-managed system could offer.
My feeling is that most nix code is not distro managed but rather written by individual project maintainers. We only bother contributing something to nixpkgs if we think it's widely applicable.
> But if it's trivial to reliably instantiate the build stack, why not just ship that instead and dispense with the special format? Then nobody has to wonder if you slipped some malware in the package before you distributed it.
This suggests to me that either you don't know how .app packaging works on macOS (or various ad-hoc packaging on Linux, such as Firefox or Ardour), or you're making a point that I'm missing.
The whole point of these non-Nix systems is precisely that you just package up bits of the build stack into the thing you distribute, and you reduce or eliminate system dependencies other than such basics as the system C library or X11.
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.
Nix is in a bit of a split/argument/fork-prone thing at the moment but it looks like this will settle into a practical/purist thing where everyone can be happy, so go in knowing which crowd is your people.
I'm not a purist so listen to one of them if you are. That said:
- flakes aren't optional or experimental, they're the default, its a small clique holding it up for years and its getting forked around by everyone serious
- flake parts is looking like a lock for the de facto flake standard, something else might come along but the leet stuff is congregating around it
- Cachix devenv is a good gateway drug: its better than Docker and easier to graduate from when it gets serious on that component
- nix-ld and FHS envs aren't a sin, they fix most all the friction bilugs and should be the default design, I overlay the shebang thing and all the unfree restrictions and all of it: the incompatible by design people are aging out, this will all work flawlessly in a year or two and you can do it today but its inside baseball
If you need to support Mac and Linux without the limitations of a strict all-OCI flow it's your best option, if you need a chance in hell against serious supply-chain attacks its your best starting point. If you need to run on a mix of metal and cloud and/or double-virtualizing is an issue its The Way.
The best super accessible resource to go from zero to "holy shit computers can do that" is vimjoyer's YouTube.
Use sops.nix and your secrets management is solved. Also by Mic92 is nixos-generators, that is basically infinitely portable to anything. juspay's GitHub, srid's GitHub, pretty much all the nixos-asia stuff is galaxy brain next level. It all works great on MacOS if you're not over it yet with the telemetry.
(sidebar: telemetry is your biggest computer problem now and your phone addiction is part of the telemetry deal. Linux and Graphene and NextDNS and Proton and stuff are worth it even for Grandma finally. I'm glad the purists do their thing, its an act of service).
> It's the choice of people who can't compromise on anything (Anduril, more and more trading shops, shit like that).
This is crucial- Nix has interhent advantages in certain industries where it IS genuinely easier than any alternatives. We're gonna see adoption start there and disseminate to general tech companies in a more consumerized form IMO
apt-get install <package name>=<version>
> And frankly, no one really needs Kubernetes, they just have it because everyone and their grandma has it. I digress, that’s a topic for another day.
Oh grow up, ffs.
1) you can python environment with dependencies! (can do that without nix)
2) you can pin dependencies by hash! (can be done with any tool mentioned in article: docker, pip, npm etc)
If you can't make reproducible dev environment in 2025 - it is 100% skill issue.
There's a lot to be said for having a single lockfile for all of them.
If I had to work with such mess of a project - I wouldnt bother with package managers at all. I just download and commit all dependencies to repo.
If dependencies are not supposed to change anyway - what is the point of downloading them from all over internet each time?
I'm specifically interested in how you handle packages that use C extensions that link system libraries.
Does it though? If using one tool is harder than using several - there is no advantage here.