Nixos configuration using more complex nix apperoaches

I have a fairly extensive flake config and I have got the hang of some Nix aspects. To strecth my knowledge I have used the sample install from ZFS Root Install flake to work through the use of elements such as:

{ pkgs, pkgs-unstable, inputs, … }:
let inherit (inputs) self;
in {


environment.systemPackages = builtins.attrValues {
inherit (pkgs-unstable)

I’m trying to avoid asking lots of (probably silly) specific questions and so I am looking for a tutorial.

Is there an easy intro to these approaches (I often find snippets that don’t help me understand the full picture, os are so complicated I get lost). Also, I’m trying to use aspects such as mkHost and mkOption, but cannot find reference to these (and any others?)


I think would be easier if you just ask the (not) silly questions :wink:

Inherit means the author loves code golf.

I think you know JSON, right?

  "a": null,
  "b": true,
  "c": 3,
  "d": 3.5,
  "e": "some string",
  "f": [ "some array", "some array" ]


{ # comments we have comments ;-)
  a = null;    #note = instead of :
  b = true;    #note ; instead of ,
  c = 3;
  d = 3.5;
  e = "some string";   # there is also multiline '' abasdfasdf ''
  f = [ "some array" "some array" ];  #note no comma
  g = { "s p a c e d" = false; h = "hard"; };

  # But there are more
  # function that receives 3 parameters
  i = param1: param2: param3:
        param1 + param2 + param2;  #spaces are ignored

  # function that receives 1 parameter and that is an
  # object (JS) / dict(python) / hashmap (java)
  # we call this attrset (just to make your life harder)
  j = { param1, param2, param3 }: 
        param1 + param2 + param2;

  # function that receives 1 parameter and that is an attrset 
  # and we don't care about other attrs of it
  k = { param1, param2, param3, ... }:
        param1 + param2 + param2;

  # function that receives 1 parameter and that is an attrset 
  # and we may use other attrs
  l = { param1, param2, param3, ... }@myVarName:
        param1 + param2 + param2 + myVarName.param4;
  # you can define some local variables
  m = let 
     param1 = 1;
     param2 = 2;
     param3 = 3; 
     in param1 + param2 + param2;

  # there are two kinds of inherit
  # means n = { na = 1; };
  n = let na = 1; in { inherit na; }; 
  # means o = 1;
  o = let 
     oa = { ob = 1; };
     inherit (oa) ob; # means ob = oa.ob;
     in ob;

  # and you may find with
  # means pb = 1;
  p = let 
     pa = { pb = 1; };
     in with pa; pb;

Thanks - that has been helpful - although I don’t really know JSON (I’m not a programmer…) but your comments make a lot of sense. so 1st question:

  outputs = { self, nixpkgs, nixpkgs-unstable, nixos-hardware, alacritty-theme, darkmatter, home-manager,>
      mkHost = hostName: system:
        nixpkgs.lib.nixosSystem {
          pkgs = import nixpkgs {
            inherit system;
            # settings to nixpkgs goes to here
            # nixpkgs.pkgs.zathura.useMupdf = true;
            nixpkgs.config.allowUnfree = true;

          specialArgs = {
            # By default, the system will only use packages from the
            # stable channel.  You can selectively install packages
            # from the unstable channel.  You can also add more
            # channels to pin package version.
            pkgs-unstable = import nixpkgs-unstable {
              inherit system;
              # settings to nixpkgs-unstable goes to here
              nixpkgs-unstable.config.allowUnfree = true;

            # make all inputs availabe in other nix files
            inherit inputs;

It is using stable (nixpkgs) and I want to use unstable, but don’t understand how to switch - or is it simply that I flip (edit pkgs - import nixpkgs to nixpkgs-unstable and specialArgs to nixpkgs). How might I use these “specialArgs”? Note, I tried the flip and now get build error involving allowDocBook.

Question 2:
The code has the line nixpkgs.config.allowUnfree = true; (and equivalent for unstable) to allow unfree packages, but I get a build error if I include any unfree package. Looking at the code at least the first one get processed (I uncommented the zathura line to help check the flow of the code).

Thanks for any pointers on this!

I’m not a programmer…

The first signal that you are a programmer is impostor syndrome.
You say you’re not a programmer and are programming (Nix is just a programming language), and you are dealing with git and terminal, on Linux. You are more programmer than average programmer :wink:

How might I use these “specialArgs”?

specialArgs is probability merged with some ‘nonSpecialArgs’ and used and create an attrset like

{ pkgs = nixpkgs; pkgs-unstable = unstable; inputs = inputs, … }

And passed all your config modules.

{ pkgs, pkgs-unstable, inputs, ... }:

{ #then you can use like
  environment.systemPackages = with pkgs; [
    firefox;               # from stable
    git;                   # from stable
    pkgs-unstable.chromium # from unstable


{ pkgs, pkgs-unstable, inputs, ... }:
  environment.systemPackages = with pkgs-unstable; [
    pkgs.firefox; # from stable
    pkgs.git;     # from stable
    chromium      # from unstable

Question 2:
What about another nixpkgs called unfree :wink: