4.9 KiB
4.9 KiB
Den Configuration Framework: Core Concepts & Guidelines
Overview
This NixOS configuration uses den, a declarative pipeline framework that shifts away from static module wiring to a system of Context Transformation and Context-Aware Aspects.
Important Resource: The den repository is vendored at _ref/den/ and its official documentation can be found at _ref/den/docs. Use these resources (via read_file, grep_search, or list_directory) anytime you need to gain a deeper understanding of den's internal behavior or available features.
1. Core Principles
- Aspects (
__functorpattern): Configurations are functions of context, not static sets. An aspect (e.g.,{ host, user, ... }: { ... }) inspects the context it receives and produces configs across domains (nixos,homeManager,darwin) simultaneously. - Context (
den.ctx): Attribute sets containing data (likehostoruser). Contexts are named (e.g.,ctx.hm-hostvsctx.host) to provide guarantees (e.g.,hm-hostproves Home Manager detection passed). - The Pipeline (
into): Data flows through a defined pipeline. One context transformsintoothers (e.g., a singlectx.hostfans out into multiplectx.usercontexts). - Providers (
provides): Aspects useprovidesto declare sub-aspects or inject configurations across contexts.
2. Idiomatic Structure
- Declaration vs. Configuration:
den.hostsandden.homesdeclare what exists (hosts, architectures, users).den.aspectsdefine how they are configured. - Domain Spanning: A single aspect file handles all relevant domains (e.g., a
gitaspect defines bothnixos.environment.systemPackagesandhomeManager.programs.git). - Composition: High-level aspects
includelower-level aspect functions.
3. The Context Pipeline
ctx.host{ host }: Resolves the host's primary aspect (den.aspects.<hostname>).ctx.default{ host }: Activates global defaults for the host.ctx.user{ host, user }: Fans out to create a context for each user on the host. Resolves user aspects (den.aspects.<username>). Crucially, host aspects can configure users here, and user aspects can configure the host.ctx.default{ host, user }: Activates global defaults for the user.ctx.hm-host{ host }: If the host supports Home Manager and has HM users, this safely imports the HM module.ctx.hm-user{ host, user }: For HM users, their config is forwarded into the host'shome-manager.users.<name>.
4. Configuration Placement
- Host Aspect (
den.aspects.<hostname>): Hardware, networking, system services. Can define defaulthomeManagersettings for all its users. - User Aspect (
den.aspects.<username>): Dotfiles, user packages, shell preferences. Can define requirednixossettings for every host the user is on. - Global Defaults (
den.ctx.default): Universal settings (e.g.,stateVersion,den._.define-user). Note: Prefer using more specific contexts (likeden.ctx.hostorden.ctx.user) overden.ctx.defaultwhenever possible. Always write it asden.ctx.defaultrather thanden.defaultto make it clear it is a context. - Feature Aspects: Granular aspects included conditionally via
<den/lib> take.exactly(orden.lib.take.exactly).
5. Common Pitfalls
- The "Lax Context" Duplicate Config Bug: A function like
({ host, ... }: { ... })inden.default.includesruns at both thectx.hostandctx.userstages, causing duplicate config errors.- Fix: Use
<den/lib> take.exactly ({ host }: ...)to run only at the host stage.
- Fix: Use
- Missing
parametricWrapper: Custom aspect trees (not auto-created by Den) that fail to forward context to their includes will throwerror: function 'anonymous lambda' called without required argument.- Fix: Wrap the custom aspect in
<den/lib> parametric.
- Fix: Wrap the custom aspect in
- Home Manager Silent Failures: If the detection gate fails (wrong OS, missing
"homeManager"class on user, or missinginputs.home-manager), HM configs won't generate.
6. Essential Library Functions (den.lib.* & Batteries)
take.exactly: Executes only if context matches arguments exactly.take.atLeast: Executes if context has at least the requested arguments.parametric: Wrapper to make an aspect forward context to itsincludes._.forward: Translates config from one domain (e.g., custom class) to another.- Batteries (
den._.*): Built-in parametric aspects (e.g.,define-user,user-shell,tty-autologin,unfree).
7. Useful Commands
nix-search-tv: Use this command to look up docs for relevant options.- Examples:
nix-search-tv preview "home-manager/ home.packages",nix-search-tv preview "nixos/ environment.systemPackages". - Prefix with
nixpkgs/for nixpkgs docs. - Use
nix-search-tv printto print all available options and packages (filter output to avoid bloating context).
- Examples: