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;
};