First entries in new official tutorial series

For those of you not aware, was recently made an official NixOS resource with the intention that it will be the home for Nix documentation.

We recently added two new tutorials we’d like you to take a look at:

These tutorials are part of a new tutorial series we’re working on that will take you from beginner to competent Nix user. We have other tutorials in the works, so there’s plenty more coming.

Feedback we’d like:

  • As a beginner are these two tutorials helpful?
  • What other tutorials would you like to see as part of a beginner series?

Some of you will inevitably ask about flakes.
Please note that we’re only documenting the stable parts of Nix at the moment, mostly because we’re very limited in bandwidth.


In, you talk about how giving stdenv unknown attributes will pass them as env variables, yet in the code sample directly after uses the env.VAR convention (instead of just VAR), which may be confusing.


Also the chapter title of feels weird, probably should be Where to go next? or Where to look next?

1 Like

In, name is introduced.

I think if the tutorial teaches name, it should also immediately teach the pname+version syntax too, because that’s a way too common footgun.


Agree. “next” also clashes a bit with the UI below it. Maybe “dig deeper” or “learn more” or “related resources”…

Creating shell environments
Before where too next, could you add something like
$ nix-shell shell.nix
@ >>> ls
shell.nix should_exist.txt

I know this is too simple for some but we all have to start somewhere.

Packaging Existing Software
For ‘Missing Dependencies’ is there no other way that an iterative try-retry?
Some programs have a lot of dependencies so this can take a long time and be a bit frustrating.
Also make install doesn’t work with sw that expects FHS.
It just seems to be that this incantation is needed but for the uninitiated lot of mumbo jumbo
that is difficult to learn without lots of examples.
Hence, each bit of the syntax needs to explained in detail and what is going on behind the scenes.
Perhaps some references to tutorials? As this seems to be just scrapting the surface.

I had the same thought and personally didn’t even know about env (yeahi I learned something from the tutorials ;)), and I’m now curious what the advantage is of one over the other?

Besides that I missed:

A short sentence why I as a user would want to use it. In the similar style as the other questions at the beginning. So that I can decide beforehand why I should invest the time to learn it.

To provide a rough example:

Why do I need this?
It allows you to run a software you don’t often need, without installing it.
Or you might have a project with specific dependencies you need in order for it to work and want to make sure that a future you or your co-developers have everything ready.

I’m still working through the packing tutorial.


I’m not sure I understand the difference between Declarative and reproducible developer environments — documentation and Creating shell environments — documentation . It seems to provide the same information, but with a different wording and, more importantly, different code. For example one uses buildInputs as a parameter to mkShell, while the other uses packages. One pins the pkgs parameter, while the other relies on the system <nixpkgs>. One uses env for environment variables, the other does not.

These might seem small things, but I remember when I started using Nix that these were exactly the things that left me confused. I think it’s important to be consistent in guides and, when there’s a difference, explain why we’re doing it differently this time and what the implications are. (providing links to various parts of the reference, once the “Reference” section is more complete, would also be a good idea in my opinion)


Feedback for packaging applications:

  • When you introduce fetchzip, a user might ask himself why he can not use the hash from the source. Often they provide already one. Later this is then explained (it’s the hash of the content, not the archive) but I would move the explanation to the first time the user gets confronted with the hash.
  • Why not use fetchzip for icat first? You can easily use the packages from the release page.
    This way you don’t have to introduce two new things at once but can focus on the more complex build process. When that is successful you can then provide an additional step to show. Something along the lines of: “hey for github, gitlab, etc. we have something better. It is better because of X and here is how it works. This is just the example for Github, you can find all the provides fetchers here: link”