How do specialArgs work?

New to Nix & NixOS :wave:


When using a flake for my NixOS system’s configuration, is there any difference between using specialArgs this way

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";

  outputs = { nixpkgs, ... } @ inputs : {
    nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = inputs;
      modules = [ ./configuration.nix ];
    };
  };
}

as opposed to this way?

{
  inputs.nixpkgs.url = "github:NixOS/nixpkgs";

  outputs = { nixpkgs, ... } @ inputs : {
    nixosConfigurations.hostname = nixpkgs.lib.nixosSystem {
      system = "x86_64-linux";
      specialArgs = { inherit inputs; };
      modules = [ ./configuration.nix ];
    };
  };
}

In know the latter is some syntaxic sugar and is equivalent to the following

      specialArgs = { inputs = inputs; };

I tried all three syntax, and from what I’ve seen, they all seem to work :thinking:

I’ve read plenty of (official & non-official) documentations, blog posts, and watched countless videos and talks but I’m still a bit lost. If there’s a good documentation I’ve missed, I’m highly interested as well :+1:

Thanks

2 Likes

From what i can understand from the source, the difference should be that specialArgs=inputs; would pass the individual members as module args while specialArgs={inherit inputs;}; passes inputs itself.

2 Likes

That would be my understanding as well but they both seem to work :thinking:

I need to do more testing to better understand this.

Thanks for the link to the source :+1:

I may have found a hint in @djacu’s excellent Function Arguments - NixOS Modules Lessons

It looks like specialArgs is always passed as an argument as well as all its attributes!

Which seems to be what the line @zimward pointed at do

({ inherit lib options config specialArgs; } // specialArgs)

Which means, pass lib, options, config, specialArgs and “merge” with all the attributes of specialArgs (using the // operator).

2 Likes