Skip to content

Type System

Source: nix/types.nix

TypePurpose
aspectsTypeTop-level container for all aspects. Used as the type for flake.aspects.
aspectSubmoduleIndividual aspect definition with class configs, includes, provides.
providerTypeUnion of all valid provider shapes (functions and aspect attrsets).

A submodule with freeformType = lazyAttrsOf (either aspectSubmodule providerType).

Provides a fixpoint: _module.args.aspects = config — so aspect definitions can reference siblings via the aspects argument.

flake.aspects = { aspects, ... }: {
a.includes = [ aspects.b ];
b.nixos = { };
};

Top-level entries can be either aspectSubmodule values (with submodule-style function args like { lib, config, options, aspect }) or providerType values (curried or direct provider functions).

A submodule defining a single aspect. Key options:

OptionTypeDefaultDescription
namestrattribute nameAspect name, auto-set
descriptionstr"Aspect ${name}"Human description
includeslistOf providerType[]Dependency providers
provides / _submodule (freeform){}Nested sub-aspects
__functorself → context → provideridentityOverride resolution behavior
resolveinternal{ class, aspect-chain? } → module
modulesinternal{ <class> = module } lazy attrset

The freeformType = lazyAttrsOf deferredModule means any key not listed above is treated as a class name with a deferred module value.

_ is an alias for provides (via mkAliasOptionModule).

The provides submodule also receives a fixpoint: _module.args.aspects = config — providers can reference siblings.

A union type covering all valid provider shapes:

providerType = either providerFn aspectSubmodule

Where providerFn = either directProviderFn curriedProviderFn:

  • directProviderFn: a function whose args are exactly { class }, { aspect-chain }, or { class, aspect-chain }.
  • curriedProviderFn: any other function that returns a providerType.

The distinction is made by isProviderFn which inspects functionArgs:

  • If the function takes exactly class and/or aspect-chain (and nothing else), it’s a direct provider.
  • Otherwise, it’s treated as curried — the user must call it with arguments first.
TypePurpose
ignoredTypeFor computed values that only exist during evaluation. Merges to null.
mkInternalHelper to create internal, invisible, read-only options with an apply function.
isSubmoduleFnChecks if a function has submodule-style args (lib, config, options, aspect).
Contribute Community Sponsor