Skip to content

Output Types

Installable types define how a flake output is built, activated, and tracked: panix ships presets for the common types and lets you declare custom types for anything else.

Each built-in type auto-infers its build path, activation mechanism, profile path, whether profile setting is needed, and its bootstrap mode; you do not configure these manually. Custom types instead declare the bootstrap mode explicitly with bootstrap_mode (see Custom Output Types).

TypeDeploysActivation
nixosConfigurationsNixOS systemswitch-to-configuration (only built-in type that supports NixOS bootstrap)
darwinConfigurationsnix-darwin (macOS)activate script
systemConfigssystem-managerbin/activate
homeConfigurationshome-manageractivationPackage/activate
nixOnDroidConfigurationsNix-on-Droidactivate script
packagesArbitrary packagesnix profile add (nix profile install under Lix)
maidConfigurationsnix-maidbin/activate

Every built-in type is bootstrappable: nixosConfigurations via the NixOS bootstrap (kexec, disko, nixos-install), the other types via the Nix installer bootstrap, which installs Nix on targets that lack it before Build, Transfer, Secrets, and Activate (see the Bootstrap guide).

System-level types activate as root (via the configured sudo_program, or bare when the SSH user is already root; a non-root target user can also be chosen with the user field, see the configuration model). User-level types activate as the SSH user. To deploy a user-level installable to a different user, set the user field on the installable (see the configuration model).

Each type’s behavior is data-driven through preset fields. User-overridable fields can be fine-tuned per-installable under preset:; type-level fields are intrinsic to the type and always taken from the declaration (or from the built-in preset for built-in types).

FieldRequiredScopePurpose
system_levelyestype-leveltrue: activation runs with sudo (system-level). false: activation runs as the SSH user (user-level)
bootstrap_modenotype-levelBootstrap mode: nix-install (Nix installer bootstrap), nixos (full NixOS bootstrap, requires system_level: true and build_path: config.system.build.toplevel), or omitted (no bootstrap). Set only under output_types declarations
output_type_attrnouser-overridableOverride the flake output attribute used in the attrpath. Defaults to the type key name
build_pathnouser-overridableAttrpath suffix for nix build (e.g. config.system.build.toplevel)
activation_pathnouser-overridableScript path within the closure to run during activation. Empty means nix profile add
profile_pathnouser-overridableNix profile path for generation tracking. Enables rollback when set. Built-ins: nixosConfigurations, darwinConfigurations, and systemConfigs also run nix-env --profile --set before activation; homeConfigurations and nixOnDroidConfigurations track the profile without setting it; packages and maidConfigurations set none
set_profilenouser-overridableRun nix-env --profile --set before activation
activation_supported_modesnouser-overridableList of valid modes (e.g. ["switch", "boot"]). If set, activation_default_mode is required
activation_non_mutating_modesnouser-overridableModes that do not mutate the target system; auto rollback is skipped for these (built-in NixOS preset: ["dry-activate"])
activation_profile_skip_modesnouser-overridableModes that skip nix-env --profile --set, so the profile keeps pointing at the current generation (built-in NixOS preset: ["test", "dry-activate"])
activation_default_modenouser-overridableDefault mode used when none is specified per-installable or via CLI
omit_type_from_attr_pathnotype-levelOmit the type key from the attrpath (bare name resolution, like packages)

Leave activation_path empty for package-like outputs installed via nix profile add (the built-in packages type); set it to a script path for activation-script outputs.

If your flake exposes outputs under a non-standard attribute name, or you need custom activation semantics, declare a type under the top-level output_types section:

output_types:
myApps:
system_level: false # required: true (root/sudo) or false (user-level)
activation_path: bin/activate # script path in the closure; empty means nix profile add
activation_supported_modes: ["apply"]
activation_default_mode: apply
fleet:
flakes:
my-infra:
installables:
myApps:
editor:
machines:
workstation:

The flake must expose the matching output under myApps.editor (only bare names under the built-in packages type get the <system> segment inserted automatically). Every installable under myApps inherits the declared preset as defaults.

  • Custom type names must not collide with built-in type names.
  • system_level must be set (validation error if missing).
  • If activation_supported_modes is declared, activation_default_mode must also be set.
  • activation_default_mode must be one of activation_supported_modes.
  • set_profile: true requires profile_path to be set.
  • bootstrap_mode: nixos requires system_level: true and build_path: config.system.build.toplevel. A per-installable build_path override is an expert knob and must still resolve to a NixOS system closure: a typo fails at Build, a non-system path fails at nixos-install.
  • Entries in activation_non_mutating_modes and activation_profile_skip_modes must be declared in activation_supported_modes.
  • Custom types are bootstrappable via bootstrap_mode in their output_types declaration: nix-install for the Nix installer bootstrap, nixos for the full NixOS bootstrap (requiring system_level: true and build_path: config.system.build.toplevel), omitted for no bootstrap. Per-installable preset: values are ignored: the type declaration wins.

The top-level attribute of the build attrpath is picked by the first matching rule:

  1. output_type_attr set: use it. workstation with output_type_attr: nixosConf builds #nixosConf.workstation.
  2. Else omit_type_from_attr_path: true: bare name only. hello builds #hello (nix resolves it under packages.<system>.<name>). This is how built-in packages works.
  3. Else (default): type key + name. alice under homeConfigurations builds #homeConfigurations.alice.

build_path, if set, is appended: #nixosConf.workstation.config.system.build.toplevel. The NixOS bootstrap builds the disko script at config.system.build.diskoScript under the same resolved output, so output_type_attr and omit_type_from_attr_path are honored for it too.

Use output_type_attr when your flake exposes NixOS systems under nixosConf.* instead of nixosConfigurations.*:

output_types:
mySystems:
system_level: true
output_type_attr: nixosConf # flake exposes systems under nixosConf.*, not mySystems.*
build_path: config.system.build.toplevel
bootstrap_mode: nixos # full NixOS bootstrap (kexec, disko, nixos-install)
activation_path: bin/switch-to-configuration
activation_supported_modes: ["switch", "boot", "test", "dry-activate"]
activation_default_mode: switch
profile_path: /nix/var/nix/profiles/system
set_profile: true

Or set it per-installable via preset: to override just one entry while keeping the built-in type:

fleet:
flakes:
my-infra:
installables:
nixosConfigurations:
workstation:
preset:
output_type_attr: nixosConf # this one builds from nixosConf.workstation
machines:
workstation: