Module Arguments

The module system allows modules and submodules to be defined using plain attribute sets, or functions that return attribute sets. When a module is a function, various attributes may be passed to it.

Top-level Module Arguments

Top-level refers to the module passed to mkFlake, or any of the modules imported into it using imports.

The standard module system arguments are available in all modules and submodules. These are chiefly config, options, lib.

getSystem

A function from system string to the config of the appropriate perSystem.

moduleWithSystem

A function that brings the perSystem module arguments. This allows a module to reference the defining flake without introducing global variables.

{ moduleWithSystem, ... }:
{
  nixosModules.default = moduleWithSystem (
    perSystem@{ config }:  # NOTE: only explicit params will be in perSystem
    nixos@{ ... }:
    {
      services.foo.package = perSystem.config.packages.foo;
      imports = [ ./nixos-foo.nix ];
    }
  );
}

withSystem

Enter the scope of a system. Example:

{ withSystem, inputs, ... }:
{
  # perSystem = { ... }: { config.packages.hello = ...; };

  flake.nixosConfigurations.foo = withSystem "x86_64-linux" (ctx@{ config, inputs', ... }:
    inputs.nixpkgs.lib.nixosSystem {
      # Expose `packages`, `inputs` and `inputs'` as module arguments.
      # Use specialArgs permits use in `imports`.
      # Note: if you publish modules for reuse, do not rely on specialArgs, but
      # on the flake scope instead. See also https://flake.parts/define-module-in-separate-file.html
      specialArgs = {
        packages = config.packages;
        inherit inputs inputs';
      };
      modules = [
        # This module could be moved into a separate file; otherwise we might
        # as well have used ctx.config.packages directly.
        ({ config, lib, packages, pkgs, ... }: {
          imports = [ ./nixos-configuration.nix ];
          services.nginx.enable = true;
          environment.systemPackages = [
            # hello package defined in perSystem
            packages.hello
          ];
        })
      ];
    });
}

perSystem module parameters

pkgs

Default: inputs.nixpkgs.legacyPackages.${system}.

Can be set via config._module.args.pkgs.

Example:

perSystem = { pkgs, ... }: {
  packages.hello = pkgs.hello;
};

inputs'

The flake inputs parameter, but with system pre-selected. Note the last character of the name, ', pronounced prime.

inputs.foo.packages.x86_64-linux.hello -> inputs'.foo.packages.hello

How? system selection is handled by the extensible function perInput.

Example:

perSystem = { inputs', ... }: {
  packages.default = inputs'.foo.packages.bar;
};

self'

The flake self parameter, but with system pre-selected.

Example:

perSystem = { pkgs, self', ... }: {
  packages.hello = pkgs.hello;
  packages.default = self'.packages.hello;
};

system

The system parameter, describing the architecture and platform of the host system (where the thing will run).

Example:

perSystem = { system, ... }: {
  packages.nixosDefaultPackages =
    let nixos = inputs.nixpkgs.lib.nixosSystem {
          modules = [ { nixpkgs.hostPlatform = system; } ];
        };
        checked = builtins.seq nixos.config.system.build.toplevel;
       # I have no idea why you would want this, but you do you
    in checked nixos.config.system.path;
};