There are a few different approaches to doing everyday development (oh use Flakes or just make it a default installed package) that it's tedious to do lots of things I've found.
It's just super nice having everything in a git backed config, for multiple systems. Working with NixOS seems like I'm simultaneously working 10 years in the future and 10 years in the past.
Just commit. Make it your daily driver, engage the community for help, and learn whatever you need to learn to do things the idiomatic way. Then settle in and get comfy.
That said, I hear you about the paralyzing number of choices. Here are some okay choices you can fall back on when you get dizzy:
- use flakes with direnv for all your projects
- when in doubt, just write the damn package
- need to use some Python library that depends on another Python library that's not in Nixpkgs? Package 'em. Package all the recursive dependencies, then package the library you wanted to use.
- want some program that's not in Nixpkgs? package it
- want to reuse a binary built for a traditional distro? package it. Look at examples in Nixpkgs of similar things (e.g., Discord, Steam)
- seek community engagement on Discourse and Matrix, not elsewhere (not Reddit, not Discord, not Slack, not IRC)
This is the best way to learn NixOS, imo. But if it seems like too much, it's not the only way.
I found using Nix package manager on my current daily-driver OS was a great way to break the ice. After translating my dotfiles to Nix and figuring out my project-specific development workflow I had given myself a strong foundation for NixOS.
Jumping into the deep end and going straight to daily-driving NixOS, is certainly also a good option.
I don't think there's a right way to do it, you are correct in that learning NixOS is pretty tedious.
Re: flakes, my personal opinion is to use flakes. While Flakes are imperfect, they still provide a lot of functionality that Nix doesn't otherwise have. In my mind, it's like Nix's equivalent of "Go modules" or something like that. I do feel like people who do not like flakes make many valid points (the boilerplate, the fact that the top-level flake expression is a subset of Nix for some reason, etc.) but the argument isn't that those problems shouldn't be solved, it's that flakes are a sub-optimal design. Since they're so proliferated throughout the ecosystem though, it is quite unlikely that Nix or any prominent fork will outright drop flakes support any time in the near future. For better or worse, Flakes are part of the Nix ecosystem for the foreseeable future. In my opinion, one may as well take advantage of that.
If you haven't already, I'd get your feet wet with installing Nix on a non-NixOS machine first, and please feel free to ask questions about Nix in the NixOS Discourse "Help" section.
I have some recommendations:
1. https://github.com/nix-community/nix-direnv - Since Nix derivations usually wrap around other build systems, the entire derivation is recomputed when any file in it changes; using direnv, you can just get your normal dev tools upon cd'ing into your project directories. This gives you a lot of the benefits of Nix during local development, but with your normal stack, and without needing to globally install anything. Importantly, this works around the problem of needing to rebuild your project every time a file changes; Nix caching isn't granular enough (at least when wrapping around other build systems as it normally does.)
2. If you are trying to build something, chances are you can find inspiration in Nixpkgs. Are you curious how you might package a Bevy game? No problem: literally search "bevy" on the Nixpkgs GitHub repo and see what comes up. I found a derivation that does: https://github.com/NixOS/nixpkgs/blob/master/pkgs/games/jump...
3. If you use flakes, you should keep the flake "schema" handy. There are a lot of different kinds of flake outputs and there are different ways to specify the same thing, which is somewhat needlessly confusing; keeping the flake schema handy will make it easier to understand what Nix is looking for in a flake, which might make it easier to see what's going on (especially if it's obfuscated.) The most important takeaway here: A command like `nix run flake#attr` will try multiple different attributes. https://nixos.wiki/wiki/flakes#Flake_schema
4. Likewise, I really recommend reading up on what NixOS modules are. NixOS modules are the basis for configurations on NixOS, and having a clear understanding of what is even going on with them is a good idea. For example, you should understand the difference between the Nix language's `import` directive, and using the NixOS modules `imports` attribute to import other NixOS modules. Understanding how the configuration merge works saves a lot of headache, makes it easier to understand how people's configurations works, and also makes it easier to modularize your own NixOS configurations, too. https://nixos.wiki/wiki/NixOS_modules
Unfortunately though, there's just no way to make it "click", and I can't guarantee that it's worth all of the effort. For me, I felt it was, but yes, there's no one correct way to do it.
But please feel free to ask questions if anything seems confusing.
Thanks for the inspiration. I actually already have nixOS installed on another laptop, but lapsed back to my Ubuntu machine out of a bit of frustration. I'll try it again and see how far I get with these tips.
Point 4 is incredibly under-marketed. Almost all of Nix/NixOS documentation focus on the language-y and build-system-y parts of Nix, and the NixOS modules are usually not talked about. Terrible state of docs doesn't help.
Knowing what are the 3 official manuals for the 3 most important projects in the core Nix ecosystem (the manuals for Nix, Nixpkgs, and NixOS, respectively) that together make up the core of the official docs will save newbies a lot of trouble.
The piece they don't tell you is that as a NixOS user, you generally want to look for a NixOS module that supports your application first. Only if you don't see one should you then directly/manually install a package into, e.g., environment.systemPackages.
The landing page that ties these reference docs together and also contains a lot more example-centric and tutorial content is nix dot dev, here: https://nix.dev/
Imo nix.dev is a great entrypoint and quickly getting better. In addition to providing a bit of a map to help you navigate the official docs, it includes the best official starting docs on flakes, and links to the highest-quality external tutorial and expository material about Nix.
Make a mental note about the 3 big reference manuals, and bookmark nix.dev, and you have everything you need to learn your way around the official docs.
There are a few different approaches to doing everyday development (oh use Flakes or just make it a default installed package) that it's tedious to do lots of things I've found.