I’ll be honest, this doesn’t look very useful. This is a tutorial of how to invoke Nix, not how to use it. The second class of target people, “who have tried to cross the chasm to using it in their daily workflows but haven’t gotten there yet”, aren’t stuck because nix-build and nix-shell “present significant cognitive overhead”* compared to nix build and nix shell. They’re stuck because they don’t know how to package things. My daily workflow does not involve rebuilding bat. My daily workflow involves building my project, and to do that with Nix, I need documentation that explains how to make Nix do that. This doesn’t provide that outside of links to existing documentation, and it’s that documentation that is, imho, most in need of attention. This just doesn’t feel like a good use of documentation-directed effort to me.
*As an aside, this claim makes no sense to me whatsoever. Learning a dozen commands isn’t any harder than learning a dozen verbs on one command.
As a person interested in nix, I find the structure and writing style of Zero to Nix far more useful than any other nix documentation I’ve read so far. Especially the opinionated style is useful as an orientation guide in the vast sea of things to learn and try out.
I’m glad it’s useful to you, then. Hopefully you’re able to get a foothold of understanding that carries you through the older strata of documentation.
Completely agree. I applaud the effort at making Nix more approachable, but Nix is still way too obscure and things that are simple to do with other package managers are still too difficult to do with Nix.
I decided to peek into Nix again after seeing this guide (I’ve tried and given up on multiple occasions in the past). I wanted to try making a C++ development environment to build a project. It’s a shame that creating a “flake.nix” file to do something even that simple is so complicated that you have to resort to using a template from a third-party. Writing the file by hand, from scratch, is basically out of the question for a beginner.
But ok, I’ll use the template. Now it’s time to add some packages. I use the “nix search” tool, which shows me a large list of package names, but doesn’t tell me anything about what’s in these packages. For example, what can I find in “clang-tools_11”? Is there a way to list the files that package includes? What about “clang11Stdenv”? That looks like it could be useful, but again, there’s no way (that I can see) to view what makes up that package or what it actually provides.
In contrast, a package manager like pacman can list all of the files that a package will install. Even Homebrew will tell me what a packages dependencies are, and will give me a hyperlink to the “formula” for a recipe, so I can see exactly how the package is defined. Is any of this possible with Nix? If it is, that’s the kind of stuff that is useful to know for using Nix as a package manger. Not rebuilding bat.
ls -l $(nix eval -f /etc/nixos/apps --raw xerox6000-6010.outPath)
What does this mean? How is anyone who hasn’t already invested dozens of hours into Nix supposed to understand this, let alone figure this out on their own?
In the end, I think this guide is like so much other Nix documentation. It provides surface level, trivial examples to give the illusion that “Nix is easy”, but leaves you completely ill-equipped for doing anything useful.
Sorry for the rant, but the hype around Nix is never ending, and I often feel like I’m being gaslit because every time I check it out I end up feeling frustrated and extremely unproductive. This doesn’t seem to match the experience of all of the ardent Nix fans out there, so I’m left feeling confused about what I’m doing wrong.
I often feel like I’m being gaslit because every time I check it out I end up feeling frustrated and extremely unproductive. This doesn’t seem to match the experience of all of the ardent Nix fans out there
I hear you. As an ardent Nix fan, I have similar experiences too. Sometimes I’ll be trying to get something packaged, and the program or its language ecosystem isn’t easily “tamed” by Nix, and I get so frustrated. And that is from someone with quite a lot of experience and background in build systems, isolation, Nix itself, and lots of experience figuring it out. Days like that I feel like I lost, and sometimes get pretty down about it. A couple years ago I “gave up” and even installed another Linux distro. (This didn’t last for more than a day…)
I hope one day Nix is as easy to use as anything else. Or even easier. It empowers me to do so much without fear, and I’m addicted to that power.
My perspective is that to do this we need to:
Produce learning material to get the interested-and-willing folks over the initial hump. Hopefully zero-to-nix helps get people there.
Expand the user base to include people in the various language ecosystems, to improve support across these ecosystems. This is a long game, but Nix is nearly 20 years in by now and we’re seeing a lot of progress.
Lean into the work that software security / provenance people have been pushing for like SBOMs. Nix gets this stuff really right, so moving this forward makes Nix more of an obvious solution.
What I don’t want to do is beat my head against the wall every time I want to try some new software. I admit that if it takes me more than an hour, I’ll sometimes boot a VM and try it out in another distro. That’s okay by me. By my count, more Nix in the world is good for everyone, and when it doesn’t serve me that is okay too.
As an aside, this line: ls -l $(nix eval -f /etc/nixos/apps --raw xerox6000-6010.outPath) seems a bit weird. However, the idea of listing what files a package will install is a bit … different in Nix, because “installing” is … a bit different. We’re going to be publishing either a z2n page, or a blog post about that soon.
For searching, at least, I’ve always used search.nixos.org rather than the CLI tool. The search results usually have a link to the package definition, though often the package source isn’t legible to someone who isn’t an advanced user. clang-tools_11 is defined here, if anything in there is helpful.
Personally, I run NixOS on some home servers and I find the declarative system configuration aspect to be incredibly helpful. But when it comes to working on individual projects, I mostly develop them in their own respective tooling, sometimes with a nix-shell or nix develop config to get the dependencies I want installed, and I only figure out how to make them buildable with Nix later on.
I’m definitely the target audience for this, and having just gone through the Quick Start I find myself agreeing with you. I was optimistic at first, as what’s there is presented clearly, but as I reached the last page I realised I don’t feel any more informed than I was in the first place and all I’ve done is run someone else’s ‘flakes’ without really understanding what’s happening (I understand broadly what is happening with each command of course, but not in any kind of sense that I could actually reproduce it myself). None of this makes Nix ‘click’ for me unfortunately. It’s a decent start, but as you said it’s just not all that helpful in its current state. It needs to provide structure and order to the learning process. You can’t just gloss over the Nix language… when you introduce me to something like this, I want to read and understand it, so that I might be able to write it myself:
But nothing I’ve read here has given me any kind of guidance on that. It’s like I’m supposed to just trust that it works. What do I take away from that? A good guide will engage my curiosity and encourage me to look deeper at what’s being presented. Shouldn’t the examples be as trimmed down as possible? Is this part really necessary?
# Systems supported
allSystems = [
"x86_64-linux" # 64-bit Intel/ARM Linux
"aarch64-linux" # 64-bit AMD Linux
"x86_64-darwin" # 64-bit Intel/ARM macOS
"aarch64-darwin" # 64-bit Apple Silicon
];
# Helper to provide system-specific attributes
nameValuePair = name: value: { inherit name value; };
genAttrs = names: f: builtins.listToAttrs (map (n: nameValuePair n (f n)) names);
forAllSystems = f: genAttrs allSystems (system: f {
pkgs = import nixpkgs { inherit system; };
});
I kind of understand what’s happening here, but that’s quite offputting if you’re trying to convince me that Nix is easy and approachable. Am I supposed to ignore this? It only makes me wonder why I would bother. I’m sure you can do things in a far more simple manner, so why this complexity? Perhaps there’s a little too much emphasis on correctness before you’ve reached the natural point of explaining why it is necessary. A nice start, and I enjoyed going through it but it needs much more work to live up to the promise of its title and ultimately I’m disappointed.
Thank you for working on this, and I hope you continue. Maybe I’ll be able to come back later and have a better experience.
Thanks for this feedback. One of the things in discussion around Flakes is system specificity and the overhead / boilerplate it tends to create. We’ll take a look at how we can simplify the documentation on this and make it more straightforward. I appreciate it!
That makes sense, thanks for the explanation. I reread my comment and I think it comes off as a bit too negative. I really did enjoy the content that is there so far, I just wanted it to keep going!
The nix.dev article looks helpful, so I’ll definitely go through that.
What I was really hoping for was more of a structured path to guide me through these concepts (a continuation from the guide). I realise how challenging that is likely to be given how broad the ecosystem is. Everyone probably has their own motivation for learning it. For me, the reproducible development environments are a big draw. For another person it might be something completely different. So I don’t know what that looks like exactly. Possibly branching paths after the quick start guide in the form of guides for the most common use cases? Whatever the case I think the hand holding needs to continue a little longer before you let people loose to discover the rest of the ecosystem for themselves. My best learning experiences have been just that. I follow the guide until I can’t help imagining all the possibilities and I am naturally compelled to go off and explore those ideas for myself. That’s where my journey really starts. If I’m going through a book (for example), that point is usually somewhere well before the middle and I may not even finish because I have enough confidence that I know what to look for. With this guide I still feel lost in a vast sea. It still feels like there’s a very large investment up front (in Nix), and I’m just trying to find the motivation to push through (hoping that it is what I imagine it to be).
Anyway, I hope my feedback is helpful in some way. I guess what I’m trying to say is that I definitely don’t expect Zero-to-Nix to be an exhaustive guide to the entire Nix ecosystem, but I do think it could carry the reader a little further, perhaps until they’re at least comfortable in writing their own simple flakes (for common use cases). A little extra confidence. That might be enough to reach that wonderful state of inspiration that drives further learning.
They provide templates for using flakes with some languages. Depending on the language you want to use to build stuff, that’s what you should look at. I think they don’t spell it because they tried to keep everything language-independent in the text, so you have to run the commands they provide to see more.
Templates are good for saving people the trouble of writing boilerplate. They are absolutely not a substitute for understanding. If you want to change something nontrivial in a project generated from a template, you still have to know how it all works.
This is incredible and exactly what Nix needed documentation wise. I really appreciate the focus on flakes and using them everywhere in these guides! Thanks so much for making this awesome resource @determinate.systems. Just shared it with all of my colleagues
Are there any plans for moving Nix flakes from experimental to stable? I see that Nix flakes are all the hype now. Even the linked guide states that:
Anyone beginning their Nix journey today should center their learning and experimentation around Nix flakes.
Do you agree with this?
I’ve been in love with NixOS for some time now but I avoided experimental features so far.
The thing is, Flakes FOMO starts to creep in but I’d rather avoid putting (even more) time into learning Nix/NixOS/nixpkgs/nix-the-command if flakes are going to be deprecated next spring.
The thing is, Flakes FOMO starts to creep in but I’d rather avoid putting (even more) time into learning Nix/NixOS/nixpkgs/nix-the-command if flakes are going to be deprecated next spring.
For what it is worth, I can’t fathom a universe where Nix actually removes Flakes. The data I’m seeing and the user interviews I’ve done show an overwhelming number of new Nix users are starting with Flakes because they’re easier and it creates a framework to learn inside.
If there is some sort of redesign or flakes2, it wouldn’t kill flakes1.
However, they are still considered to be an unstable feature by the Nix main developer. The flakes code you write is considered unstable and could break without further notice after a Nix update.
I think all the knowledge you get without flakes would be still transferable to a flake-based setup. Flakes are nice for a few usecases. Most importantly, pinning and mixing packages from different sources. If you don’t have urgent needs related to these two things, you can postpone migrating to flakes.
Regarding experimental features, I find the new nix command something worth looking into. The CLI is much simpler and nicer.
Part of the issue is that the RFC committee doesn’t want to rubber-stamp flakes just because a lot of people, lead by a few influential people, are all using the same unofficial and experimental feature. It makes a mockery of the RFC process and skips over a thorough design review. If flakes are really the way forward, some of all this energy should go into getting the RFC officially pushed through.
This is a much better experience than stumbling between the official guides/wiki/tutorials online. Even though flakes are still experimental I think it’s a better starting place. Cutting out channels makes setting up NixOS machines that much easier. I also love that the templates utilize devShells Python Example. I do the same thing for my shells but make a new one for each version of python and a simple bash function for jumping into them. Great for any language you want to develop or experiment with.
I don’t understand how the JavaScript flake is supposed to work. Isn’t nix build sandboxed, preventing network access? The documentation I’ve found isn’t very clear on this, but I think network access is blocked inside the sandbox as I’m getting DNS errors:
FetchError: request to https://registry.npmjs.org/vite/-/vite-3.2.4.tgz failed, reason: getaddrinfo EAI_AGAIN registry.npmjs.org
If there’s no network access, then how would the pnpm install in buildPhase work?
I tried disabling the sandbox in nix.conf too, but that just gave me some strange permission errors like:
That’s a relief! Unfortunately I’m now seeing this error from nix build:
npm ERR! [esbuild] Failed to find package "esbuild-linux-64" on the file system
I think that this is because package-lock.json was generated on a macOS system so it only includes esbuild-darwin-arm64 and not esbuild-linux-64 (or other architectures).
I’ll be honest, this doesn’t look very useful. This is a tutorial of how to invoke Nix, not how to use it. The second class of target people, “who have tried to cross the chasm to using it in their daily workflows but haven’t gotten there yet”, aren’t stuck because
nix-build
andnix-shell
“present significant cognitive overhead”* compared tonix build
andnix shell
. They’re stuck because they don’t know how to package things. My daily workflow does not involve rebuildingbat
. My daily workflow involves building my project, and to do that with Nix, I need documentation that explains how to make Nix do that. This doesn’t provide that outside of links to existing documentation, and it’s that documentation that is, imho, most in need of attention. This just doesn’t feel like a good use of documentation-directed effort to me.*As an aside, this claim makes no sense to me whatsoever. Learning a dozen commands isn’t any harder than learning a dozen verbs on one command.
As a person interested in nix, I find the structure and writing style of Zero to Nix far more useful than any other nix documentation I’ve read so far. Especially the opinionated style is useful as an orientation guide in the vast sea of things to learn and try out.
I’m glad it’s useful to you, then. Hopefully you’re able to get a foothold of understanding that carries you through the older strata of documentation.
Completely agree. I applaud the effort at making Nix more approachable, but Nix is still way too obscure and things that are simple to do with other package managers are still too difficult to do with Nix.
I decided to peek into Nix again after seeing this guide (I’ve tried and given up on multiple occasions in the past). I wanted to try making a C++ development environment to build a project. It’s a shame that creating a “flake.nix” file to do something even that simple is so complicated that you have to resort to using a template from a third-party. Writing the file by hand, from scratch, is basically out of the question for a beginner.
But ok, I’ll use the template. Now it’s time to add some packages. I use the “nix search” tool, which shows me a large list of package names, but doesn’t tell me anything about what’s in these packages. For example, what can I find in “clang-tools_11”? Is there a way to list the files that package includes? What about “clang11Stdenv”? That looks like it could be useful, but again, there’s no way (that I can see) to view what makes up that package or what it actually provides.
In contrast, a package manager like pacman can list all of the files that a package will install. Even Homebrew will tell me what a packages dependencies are, and will give me a hyperlink to the “formula” for a recipe, so I can see exactly how the package is defined. Is any of this possible with Nix? If it is, that’s the kind of stuff that is useful to know for using Nix as a package manger. Not rebuilding bat.
The top search result for “how to view contents of a package in Nix” shows this answer:
What does this mean? How is anyone who hasn’t already invested dozens of hours into Nix supposed to understand this, let alone figure this out on their own?
In the end, I think this guide is like so much other Nix documentation. It provides surface level, trivial examples to give the illusion that “Nix is easy”, but leaves you completely ill-equipped for doing anything useful.
Sorry for the rant, but the hype around Nix is never ending, and I often feel like I’m being gaslit because every time I check it out I end up feeling frustrated and extremely unproductive. This doesn’t seem to match the experience of all of the ardent Nix fans out there, so I’m left feeling confused about what I’m doing wrong.
I hear you. As an ardent Nix fan, I have similar experiences too. Sometimes I’ll be trying to get something packaged, and the program or its language ecosystem isn’t easily “tamed” by Nix, and I get so frustrated. And that is from someone with quite a lot of experience and background in build systems, isolation, Nix itself, and lots of experience figuring it out. Days like that I feel like I lost, and sometimes get pretty down about it. A couple years ago I “gave up” and even installed another Linux distro. (This didn’t last for more than a day…)
I hope one day Nix is as easy to use as anything else. Or even easier. It empowers me to do so much without fear, and I’m addicted to that power.
My perspective is that to do this we need to:
What I don’t want to do is beat my head against the wall every time I want to try some new software. I admit that if it takes me more than an hour, I’ll sometimes boot a VM and try it out in another distro. That’s okay by me. By my count, more Nix in the world is good for everyone, and when it doesn’t serve me that is okay too.
As an aside, this line:
ls -l $(nix eval -f /etc/nixos/apps --raw xerox6000-6010.outPath)
seems a bit weird. However, the idea of listing what files a package will install is a bit … different in Nix, because “installing” is … a bit different. We’re going to be publishing either a z2n page, or a blog post about that soon.For searching, at least, I’ve always used search.nixos.org rather than the CLI tool. The search results usually have a link to the package definition, though often the package source isn’t legible to someone who isn’t an advanced user.
clang-tools_11
is defined here, if anything in there is helpful.Personally, I run NixOS on some home servers and I find the declarative system configuration aspect to be incredibly helpful. But when it comes to working on individual projects, I mostly develop them in their own respective tooling, sometimes with a
nix-shell
ornix develop
config to get the dependencies I want installed, and I only figure out how to make them buildable with Nix later on.I’m definitely the target audience for this, and having just gone through the Quick Start I find myself agreeing with you. I was optimistic at first, as what’s there is presented clearly, but as I reached the last page I realised I don’t feel any more informed than I was in the first place and all I’ve done is run someone else’s ‘flakes’ without really understanding what’s happening (I understand broadly what is happening with each command of course, but not in any kind of sense that I could actually reproduce it myself). None of this makes Nix ‘click’ for me unfortunately. It’s a decent start, but as you said it’s just not all that helpful in its current state. It needs to provide structure and order to the learning process. You can’t just gloss over the Nix language… when you introduce me to something like this, I want to read and understand it, so that I might be able to write it myself:
https://github.com/DeterminateSystems/zero-to-nix/blob/main/nix/templates/dev/javascript/flake.nix
But nothing I’ve read here has given me any kind of guidance on that. It’s like I’m supposed to just trust that it works. What do I take away from that? A good guide will engage my curiosity and encourage me to look deeper at what’s being presented. Shouldn’t the examples be as trimmed down as possible? Is this part really necessary?
I kind of understand what’s happening here, but that’s quite offputting if you’re trying to convince me that Nix is easy and approachable. Am I supposed to ignore this? It only makes me wonder why I would bother. I’m sure you can do things in a far more simple manner, so why this complexity? Perhaps there’s a little too much emphasis on correctness before you’ve reached the natural point of explaining why it is necessary. A nice start, and I enjoyed going through it but it needs much more work to live up to the promise of its title and ultimately I’m disappointed.
Thank you for working on this, and I hope you continue. Maybe I’ll be able to come back later and have a better experience.
Thanks for this feedback. One of the things in discussion around Flakes is system specificity and the overhead / boilerplate it tends to create. We’ll take a look at how we can simplify the documentation on this and make it more straightforward. I appreciate it!
That makes sense, thanks for the explanation. I reread my comment and I think it comes off as a bit too negative. I really did enjoy the content that is there so far, I just wanted it to keep going!
Whew, that is really great to hear =).
For what it is worth…
The nix.dev article looks helpful, so I’ll definitely go through that.
What I was really hoping for was more of a structured path to guide me through these concepts (a continuation from the guide). I realise how challenging that is likely to be given how broad the ecosystem is. Everyone probably has their own motivation for learning it. For me, the reproducible development environments are a big draw. For another person it might be something completely different. So I don’t know what that looks like exactly. Possibly branching paths after the quick start guide in the form of guides for the most common use cases? Whatever the case I think the hand holding needs to continue a little longer before you let people loose to discover the rest of the ecosystem for themselves. My best learning experiences have been just that. I follow the guide until I can’t help imagining all the possibilities and I am naturally compelled to go off and explore those ideas for myself. That’s where my journey really starts. If I’m going through a book (for example), that point is usually somewhere well before the middle and I may not even finish because I have enough confidence that I know what to look for. With this guide I still feel lost in a vast sea. It still feels like there’s a very large investment up front (in Nix), and I’m just trying to find the motivation to push through (hoping that it is what I imagine it to be).
Anyway, I hope my feedback is helpful in some way. I guess what I’m trying to say is that I definitely don’t expect Zero-to-Nix to be an exhaustive guide to the entire Nix ecosystem, but I do think it could carry the reader a little further, perhaps until they’re at least comfortable in writing their own simple flakes (for common use cases). A little extra confidence. That might be enough to reach that wonderful state of inspiration that drives further learning.
They provide templates for using flakes with some languages. Depending on the language you want to use to build stuff, that’s what you should look at. I think they don’t spell it because they tried to keep everything language-independent in the text, so you have to run the commands they provide to see more.
Templates are good for saving people the trouble of writing boilerplate. They are absolutely not a substitute for understanding. If you want to change something nontrivial in a project generated from a template, you still have to know how it all works.
This is incredible and exactly what Nix needed documentation wise. I really appreciate the focus on flakes and using them everywhere in these guides! Thanks so much for making this awesome resource @determinate.systems. Just shared it with all of my colleagues
Are there any plans for moving Nix flakes from experimental to stable? I see that Nix flakes are all the hype now. Even the linked guide states that:
Do you agree with this?
I’ve been in love with NixOS for some time now but I avoided experimental features so far.
The thing is, Flakes FOMO starts to creep in but I’d rather avoid putting (even more) time into learning Nix/NixOS/nixpkgs/nix-the-command if flakes are going to be deprecated next spring.
For what it is worth, I can’t fathom a universe where Nix actually removes Flakes. The data I’m seeing and the user interviews I’ve done show an overwhelming number of new Nix users are starting with Flakes because they’re easier and it creates a framework to learn inside.
If there is some sort of redesign or flakes2, it wouldn’t kill flakes1.
I agree, it seems like flakes are here to stay.
However, they are still considered to be an unstable feature by the Nix main developer. The flakes code you write is considered unstable and could break without further notice after a Nix update.
I think all the knowledge you get without flakes would be still transferable to a flake-based setup. Flakes are nice for a few usecases. Most importantly, pinning and mixing packages from different sources. If you don’t have urgent needs related to these two things, you can postpone migrating to flakes.
Regarding experimental features, I find the new nix command something worth looking into. The CLI is much simpler and nicer.
Part of the issue is that the RFC committee doesn’t want to rubber-stamp flakes just because a lot of people, lead by a few influential people, are all using the same unofficial and experimental feature. It makes a mockery of the RFC process and skips over a thorough design review. If flakes are really the way forward, some of all this energy should go into getting the RFC officially pushed through.
Good content but they should’ve use a different name for their intallation script though; the official sounding “nix installer” is misleading.
Exactly what I’ve been looking for! Fantastic. Will try using it now.
This is a much better experience than stumbling between the official guides/wiki/tutorials online. Even though flakes are still experimental I think it’s a better starting place. Cutting out channels makes setting up NixOS machines that much easier. I also love that the templates utilize devShells Python Example. I do the same thing for my shells but make a new one for each version of python and a simple bash function for jumping into them. Great for any language you want to develop or experiment with.
I’ve been having trouble with this:
https://zero-to-nix.com/start/nix-build-flake
I don’t understand how the JavaScript flake is supposed to work. Isn’t
nix build
sandboxed, preventing network access? The documentation I’ve found isn’t very clear on this, but I think network access is blocked inside the sandbox as I’m getting DNS errors:If there’s no network access, then how would the
pnpm install
inbuildPhase
work?I tried disabling the sandbox in nix.conf too, but that just gave me some strange permission errors like:
Oops, a generous contributor sent a PR for that. Thanks for pointing it out, it should be fixed now: https://github.com/DeterminateSystems/zero-to-nix/pull/174
That’s a relief! Unfortunately I’m now seeing this error from
nix build
:I think that this is because package-lock.json was generated on a macOS system so it only includes
esbuild-darwin-arm64
and notesbuild-linux-64
(or other architectures).Edit: Sorry, I submitted an issue for this.