How to actually understand nix?

Hello. I am very interested in flakes, and I wrote one to have a simple development environment and another one to build a rust package. But getting to that point was very very much work. And I still do not really understand what is going on in the code. I just do not know where I look for documentation. Where can I find actually good descriptions of what functions do? How do i actually grasp stuff and understand what the heck is going on in a more complicated nix file? I went through the manual, the basics of the nix language and some other stuff… but it is still just so confusing.

I would like to be able to create flakes with best practice code for example completely on my own, really understand what is going on and do some amazing things with it, but I cannot even do the simplest stuff because I do not find where to look for good docs.

Can anyone who is maybe experienced please help me, so I can really start achieving a lot with the nix ecosystem? I am kind of stuck…

What i currently did when i did not know anything was just ask ALL the time on the discord server and matrix channel, but it honestly kind of sucks asking every time someone who has a lot of expertise

First of all, you need to learn where the (not so clear) boundaries are…

There are (not exhaustive):

  • nix the build tool,
  • nix the expression language,
  • flakes as a project description,
  • nixpkgs library functions,
  • nixpkgs builders and fetchers,
  • nixpkgs packages,
  • external builders (like dream2nix or cargo2nix)

All of these are individual things to learn, and in case of the builders, you often learn the details depending on their ecosystem.

I maybe keeping repeating myself, and this might actually be a not so popular opinion, but the best way to learn the nix(pkgs) ecosystem is to keep using it. Keep asking questions, try to answer the questions you see and have a slight idea about (often there is not much need to explain the nitty gritty details as long as an initial solution is provided and the other user gets unstuck).

I am sorry that this is not a straight forward “from zero to hero” path, but the nix ecosystem and all of its sub ecosystems are just far to complex to give you a list of URLs or blogs to skim through.

1 Like

When I ask questions on element, then I get some answer and then on the discord server someone says my solution is not good and i should change it and that takes 2h again…

I agree that there are some opposing opinions about some things, and the community kind of split based on some of these between Discord and Matrix, this shouldn’t be a reason to stop asking though. On the other hand side though, this perception of the opposing opinions between both halfs of the community is probably not even true, though only perceived that way, due to “vocal minorities”, aka most active members.

The solution would be to decide on one of the subcommunities for now and stay with that, ignoring the other one until you are confident enough to justify your decissions.

Despite of that, asking the same question on both platforms at approximately same time is usually considered bad netiquette and often refered to as “crossposting”.

In terms of learning specifically the language itself, so you understand complex nix files a bit better, I think the process is something like

  1. Use the basic constructs as copy-pasted from various places
  2. Gain a basic understanding of what attrsets are and how you can operate on them
  3. Become confident in browsing the reference docs for the “standard” library functions, both in nixpkgs and the nix manual
  4. Start understanding more exotic constructs like inherit, let in, @ attrs, with, …
  5. Figure out function declarations, function calls, imports
  6. Understand the difference between NixOS modules and normal nix code, including inline module definitions
  7. Read the nix pills and figure out callPackage

Not necessarily in order… But I think those are the core competencies you’ll build up to tackle arbitrarily complex nix files. Understanding of concepts like the nix store will slowly trickle in as you experiment, too.

Part of the complexity is definitely figuring out functional programming languages if you don’t have any background in them. While I generally think it’s a good fit for the types of work we do with nix, I’ve also definitely often heard long-term programmers complain about having to think “backwards”. It can take a while to adjust to how these languages work, even with relatively simple ones like nix.

Don’t get too intimidated, start with simple projects. Packaging simple things like fonts or templated configuration files is much simpler than fully compiled projects, let alone rust/python/java/go/whatever, and you should probably try writing modules before going on to more complex packages. Once you’ve figured out basic packaging and modules, you can then go on to writing functions that build the same thing in subtly different ways, your own specialized composite builders (for tests for example), modules that change based on some input data, etc.

Also never underestimate the value of reading existing code. If you need to figure out how to do something, go see if someone has done it in nixpkgs before, and read their code.

I’d also caution you from trying to understand third party projects like dream2nix, poetry2nix, niv, the various flake “helpers” & co until you understand roughly how they work - projects like those obscure what’s going on under the hood, so you won’t really understand what’s happening if you don’t get the basics yet. You can still use them, of course, but don’t feel bad if you’re just copy-pasting code. They’re not simple.

Despite everybody’s complaints, the nix, nixos and nixpkgs manuals are quite good, by the way. Once you start understanding the nix manuals’ explanation of the language and how it maps to things you’ve written you should consider yourself pretty much there.

2 Likes

When I develop in other languages, I find using a debugger helps me a lot to see what is going on and it helps learning too. What are the best “tool tricks” to facilitate learning Nix? I don’t use the repl much at all for example, is that a mistake?

1 Like

I don’t use the nix repl much either, but it has helped me explore things I wasn’t familiar with in the past. Loading nixpkgs and tab-completing through its outputs can show you a lot about how packages and derivations actually work.

It’s also nice for putting together complex function chains with a bit of test data. Generally I find myself writing very little truly complex nix code though, so this is a rare use case for me.

Personally, I use the lib.debug functions quite a bit when trying to understand why some configuration isn’t working. Looking at your variable contents can help spot false assumptions when the billion lines of --show-trace don’t do much for you…

2 Likes