2023-07-17 Tutorial Series Call for Feedback

The Learning Journey Working Group is working on its next set of tutorial outlines.

We make these outlines so that contributors that want to help out and write tutorials can just pick something up and start working on something with minimal onboarding time.
We solicit feedback in this way because we’re a small team with limited Nix experience compared to many of the experts in this community, so we’d like to leverage the community’s expertise.

This is the second call for feedback, the first is posted here: 2023-06-19 Tutorial Series Call for Feedback #1. That call for feedback was posted in a relatively low-traffic part of this site, so we didn’t get much feedback (that’s on me).

The intention is to post these once per month since that’s the cadence at which we’ve decided to work on these tutorial outlines.

How you can help

Suggest activities

For each of these tutorials we’d like the user to walk through some activity that will put them into contact with the topic of the tutorial.

We’ll have some ideas of activities users can walk through on their own, but more suggestions at this stage of the process will always be better.

So, the first thing you can do is provide suggestions for activities that users can do on a particular topic.

Where do users get stuck?

The next thing you can do is provide us with insight into where users get stuck on these topics.

Even if all of us in the Working Group were experts, we don’t know everyone using Nix, and we certainly don’t know where everyone gets stuck.

If you have experience helping users with these topics, please point out the major pain points or stumbling blocks.

Make us aware of the traps

Anyone who has ever used a computer has had the “how hard could it be” experience that turns into a rabbit hole of complexity.

If you know that a particular topic we’ve chosen has hidden complexities, we’d like to hear about them so that we can keep the reader on a happy path until we intentionally decide to present any complexities.

For example, if you bring python310 and python310Packages.pip into a nix-shell -p environment, you can’t just install Python packages with pip install like you would outside of a Nix shell.

Tutorial ideas

Feel free to leave comments on the GitHub issues linked below or leave comments in this thread.

nix-shell -p

GitHub issue

The intention is for this tutorial to be the first interaction a user has with Nix since it has minimal weirdness: you say “put me in a shell with these packages”.

The tutorial needs to provide an activity in which using nix-shell -p solves a real problem. Note that this doesn’t have to be a huge problem, it just has to be a real motivating example rather than a contrived situation in which nix-shell -p can be used to help you out of the situation.

The common use case for nix-shell -p is probably “I want to run a single command with this program and then I never want to see it again,” but it’s hard to write a tutorial around that.


  • Are there any common situations in which you’ve used nix-shell -p?
  • Do you ever use reproducible scripts with nix-shell -p i.e. do you have scripts that have a #!/usr/bin/env nix-shell line followed by a # nix-shell -i <interpreter> -p <packages> line?


GitHub issue

This tutorial is already pretty well defined, but concrete ideas for which aspects of shell.nix you typically configure are welcome. For example, setting environment variables is trivial, but also really useful. Modifying hooks are useful for doing setup when you enter the environment.


  • Which configuration features of a shell.nix file do you use?
  • What’s your workflow when you use a shell.nix to configure a development environment? Do you always type nix-shell or do you use something like direnv? Do you have any automatic setup done for you with shell hooks or other mechanisms? If so, what’s the use case?

Pinning nixpkgs

GitHub issue

The idea here is to show users why they might want to pin nixpkgs, and then show them how to do so with different levels of reproducibility/rigor. If you’re iterating on a package it can be surprising when it suddenly decides to rebuild/substitute a bunch of dependencies (“haven’t I already built this?”).


  • Do you have any tricks or shortcuts for looking up the particular nixpkgs revision you want to pin to? This could be a script or one-liner that retrieves the commit hash, etc.
  • Other than maximum reproducibility and avoiding rebuilds, do you have other use cases for pinning nixpkgs?
  • Are there any aspects of pinning nixpkgs that you’d like to see discussed?

With NixOS gaining a bit more of popularity we can also observe an increasing number of posts in this forum with people getting stuck at the very beginning, like

  • “I did nix-env -iA foo, why is $app not in start menu” → solution: log out and in again, nix-env is an anti-pattern
  • “I just downloaded program and it says ‘~/bin/app: program not found’ but it us there” → solution: it is actually a linker issue, the binary expects a FHS
  • “I added $foo to my configuration.nix but it still can’t be found” → solution: nixos-rebuild…
  • “program $foo doesn’t update” → solution: update channels; check if on old stable

And also some general advice on keeping the config lean and using per-project shell.nix (or even better: Flakes!) and nix-shell / nix run for software that is not used often.

We need a FAQ-in-disguise (aka as “first steps after installation”) in a prominent place that we can link to. Just a single page that covers those topics in a quite straightforward (but still polite) manner. And from that in we can branch out to the tutorial series.

Otherwise: It feels documentation has improved a lot since I joined the Nix community a few years ago (or I get better at searching stuff). A really big THANK YOU to everyone contributing to the docs.


Not using nix-env but system config or HM doesn’t necessarily help. From what I learned during chat report the activation scripts are not reliably triggering a cache refresh.

Whenever I see this one in chat or forum, I am wondering for a brief moment… Where or what do we need to patch to make the error more ergonomic…

A shebang alike #!/bin/missing tells you what the problem is. But a missing interpreter in an ELF gives a misleading error…

If $foo is a binary, I tend to agree, though quite often $foo is a library.

Some poeple even add libraries to their system configuration when a nix-build fails…

This one requires a lot of careful and distinct education.

I disagree. I’m fine with documenting flakes in the nix manual as an experimental feature. I am fine seeing blog posts using them and repos using them. I am fine with third parties providing “flake first” docs, but I am absolutely opposed to official documentation that suggests to use flakes over nix path based non-experimental nix!

Once flakes have been stabilised we can start incorporating them into official ressources more…

1 Like

I don’t have gparted installed on my system because I only use it every once in a while.
When I need it, I call it with nix-shell -p. Or recently I wanted to check that nvidia-offload is working correctly so I got nvtop with nix-shell -p.

Not yet but I should probably add it to my install script.
It’s actually something that I just recently rediscovered.

This, direnv is very helpful in combination with nix-shell. I’m even trying to replace container based development environments with.
For example in this project: Nebucatnetzer/django_htmx_examples: A collection of examples on how to do various tasks with HTMX and Django. - django_htmx_examples - Gitea: Git with a cup of tea I’m using the application overmind to start a Postgres DB and the Django development server.
Nix-Shell provides the packages and direnv sets everything up. A little BASH script then lets you start and stop the services. It was inspired by lgug2z on Mastodon and they wrote a post about it.

As for getting stuck:
Most of the time it has to do with learning how applications are behaving and how to configure them from scratch if there isn’t a distro provided base config and the default paths aren’t available.
E.g. recently I built a nix-shell for a Python environment at work which I use in WSL1. WSL1 has a problem with certain NodeJS versions including the one from Nixpkgs.
Therefore I used NodeJS from the upstream PPA (the WSL is an Ubuntu 22.04 installation).
However I pointed LD_LIBRARY_PATH to ${pkgs.stdenv.cc.cc.lib}/lib in order to make certain PyPi packages work which then caused NodeJS to break because it didn’t include the correct version of glibc or so.
So apparently it might not be the best idea to customize LD_LIBRARY_PATH if you’re not on NixOS where every package brings it’s own dependencies.