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.
Built-In Types
Section titled “Built-In Types”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).
| Type | Deploys | Activation |
|---|---|---|
nixosConfigurations | NixOS system | switch-to-configuration (only built-in type that supports NixOS bootstrap) |
darwinConfigurations | nix-darwin (macOS) | activate script |
systemConfigs | system-manager | bin/activate |
homeConfigurations | home-manager | activationPackage/activate |
nixOnDroidConfigurations | Nix-on-Droid | activate script |
packages | Arbitrary packages | nix profile add (nix profile install under Lix) |
maidConfigurations | nix-maid | bin/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).
Preset Fields
Section titled “Preset Fields”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).
| Field | Required | Scope | Purpose |
|---|---|---|---|
system_level | yes | type-level | true: activation runs with sudo (system-level). false: activation runs as the SSH user (user-level) |
bootstrap_mode | no | type-level | Bootstrap 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_attr | no | user-overridable | Override the flake output attribute used in the attrpath. Defaults to the type key name |
build_path | no | user-overridable | Attrpath suffix for nix build (e.g. config.system.build.toplevel) |
activation_path | no | user-overridable | Script path within the closure to run during activation. Empty means nix profile add |
profile_path | no | user-overridable | Nix 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_profile | no | user-overridable | Run nix-env --profile --set before activation |
activation_supported_modes | no | user-overridable | List of valid modes (e.g. ["switch", "boot"]). If set, activation_default_mode is required |
activation_non_mutating_modes | no | user-overridable | Modes that do not mutate the target system; auto rollback is skipped for these (built-in NixOS preset: ["dry-activate"]) |
activation_profile_skip_modes | no | user-overridable | Modes that skip nix-env --profile --set, so the profile keeps pointing at the current generation (built-in NixOS preset: ["test", "dry-activate"]) |
activation_default_mode | no | user-overridable | Default mode used when none is specified per-installable or via CLI |
omit_type_from_attr_path | no | type-level | Omit 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.
Custom Output Types
Section titled “Custom Output Types”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.
Validation Rules
Section titled “Validation Rules”- Custom type names must not collide with built-in type names.
system_levelmust be set (validation error if missing).- If
activation_supported_modesis declared,activation_default_modemust also be set. activation_default_modemust be one ofactivation_supported_modes.set_profile: truerequiresprofile_pathto be set.bootstrap_mode: nixosrequiressystem_level: trueandbuild_path: config.system.build.toplevel. A per-installablebuild_pathoverride 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_modesandactivation_profile_skip_modesmust be declared inactivation_supported_modes. - Custom types are bootstrappable via
bootstrap_modein theiroutput_typesdeclaration:nix-installfor the Nix installer bootstrap,nixosfor the full NixOS bootstrap (requiringsystem_level: trueandbuild_path: config.system.build.toplevel), omitted for no bootstrap. Per-installablepreset:values are ignored: the type declaration wins.
Attrpath Resolution
Section titled “Attrpath Resolution”The top-level attribute of the build attrpath is picked by the first matching rule:
output_type_attrset: use it.workstationwithoutput_type_attr: nixosConfbuilds#nixosConf.workstation.- Else
omit_type_from_attr_path: true: bare name only.hellobuilds#hello(nix resolves it underpackages.<system>.<name>). This is how built-inpackagesworks. - Else (default): type key + name.
aliceunderhomeConfigurationsbuilds#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: trueOr 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: