Trying to understand Nix, Flakes, Dev Env

I really enjoying using NixOS, and thinking to replace Debian with NixOS. But I still don’t understand some points. Note: Sorry for making 3 post :smiley:

  • System
  • I set-up flake for the system and home-manager. Should I continue use nixos-rebuild switch --upgrade for upgrade the system, or just with flakes sudo nixos-rebuild switch --flake .#nixos
    • Watching many tutorials, they copy the /etc/nixos/configuration.nix to the flake dir. Is there any problem making a link with ln -s ?
  • After upgrading the system, in system.stateVersion = "23.05"; automatically will point to the new version, or should I re-write to point to the new version ?

  • I develop with C++, CMake, SDL2, OpenGL, Zig, C#, Godot, Unity3D. The thing is:
  • Should I use flake for making a development environment ?
    • Because I made a flake for C++, inside I have:
#devShell = pkgs.mkShell.override { stdenv = pkgs.clangStdenv; } rec { ## This is for Clang
#devShell = pkgs.mkShell.override { stdenv = pkgs.gcc13Stdenv; } rec { ## This is for GCC
    • But if I set pkgs.gcc13Stdenv, and inside of packages I add libstdcxxClang, make the cmake choose Clang to compile. Why ?

  • Inside of flakes using nix develop
  • In my flake where is my system, I install zsh, but once inside of the flake for C++ using nix develop, cant use zsh.
    • Each flake is a “different system”, cant inherit the packages from the OS ?
    • Should also add to the flake add the same configuration to this C++ flake ?
  • How to use VS Code to get inside of this flake ?
    • Once inside the flake, I do, code .
  • Just now, noticed that, yesterday I did nix-collect-garbage, nix-collect-garbage --delete-old, nix-collect-garbage-d. And trying to enter to this flake using nix develop, start again to download the packages.
    • Is there a way to keep this packages ?

Edit: Just one more thing :smiley:

  • AppImages
nix-shell -p appimage-run
appimage-run $AppImageFile
  • Trying to use yuzuea.appimage, (I know that nixos has it)
    Note: I get a weird thing: I am trying NixOs in my laptop but using ssh from my Desktop to install and etc… The thing is, if in the laptop when I try appimage-run yuzu.appimage, shows an error about qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in ""
    BUT, in my desktop if I try nix-shell -p appimage-run appimage-run yuzu.appimage WORKS ???
1 Like

AFAIR this command doesn’t have an effect for flakes. If you want to update your inputs use nix flake update or nix flake lock respectively.

The configuration should be part of the flake. And I am not sure about the semantics for links pointing to the outside world.

I would definitely prefer to either have the config copied into the flake itself (where with “flake” I mean the whole repository containing the flake.nix file) or create the flake at /etc/nixos to make sure the config is part of it.

Do not touch system.stateVersion unless you know why.

To actually update between releases you have to change the input URLs accordingly.

Whether you prefer flakes or channel based development environments is up to you, but you should create an individual environment for each and every project you touch.

You can. nix develop . -c zsh (or nix develop . -c $SHELL) are often suggested as a workaround. Another nice workaround that also allows “auto activation” of the environments based on your pwd, would be direnv with the nix-direnv plugin (the latter enables flakes support and also creates a GC root for shells you enter, but if you don’t want either bare direnv has basic nix support).

You are not “inside the flake”, you are “inside the dev environment”, but yes. You first enter the environment, then you use the terminal to start your IDE/editor. Some larger editors are known to have problems with this (looking at you IntelliJ).

For many editors there are also direnv based plugins available, that work more or less. According to my knowledge all of them are prone to races, as basically no editor has support for plugin initialisation order or priorities.

As said direnv + nix-direnv will create GC roots for you, though on the cost of manually having to clean them up regularly, as they are not managed like regular profiles and invisible to the age based GC system.


You can have your config repo wherever you want and then symlink flake.nix to /etc/nixos/flake.nix
Afterwards only sudo nixos-rebuild switch is required.
NixOS will automatically follow the symlink and choose the NixOS configuration matching to the hostname.

direnv actually has flake support built-in now!

1 Like

I find this option to be very confusing.
The only proper documentation that I could find is next to the option:

So far I read the release manual and checked if a database gets updated or something is mentioned related to the stateVersion and if nothing was mentioned and the first boot worked fine I changed it to match the current release.

What are the best practices for handling this?
How do I know which packages are depending on it?
What happens if we never change it?

I’ve written an article on my employer’s blog about system.stateVersion a while ago which also gives a practical example where this was useful: Safe service upgrades using system.stateVersion

Perhaps this helps understanding that better :slight_smile:


Thank you for the article, that was actually very helpful.
Would you therefore recommend to always hardcode the packages for e.g. postgres?

Yes. As soon as you upgrade to a newer postgres major-version, you’ll have to do it anyways. This is mainly a safeguard to make sure we don’t mess with people’s data.

I usually follow the following steps when doing that btw: NixOS 23.05 manual | Nix & NixOS

1 Like

Okay this makes sense now, thank you :+1: