Skip to content

Context-aware Dendritic Nix

Context-driven, aspect-oriented, cross-class Nix configurations

At its core, Den is a library for activating Nix-modules configuration aspects via context transformations.

On top of the library, Den provides a framework for the common case of NixOS/Darwin/Home-Manager.

Den embraces to your Nix choices and does not impose itself. All parts of Den are optional and replaceable.

Den builds on flake-aspectsparametric aspects, and provides a declarative context-pipeline as cutting-points for these aspects.

Context Transformation

Data flows through a declarative pipeline of contexts. Each stage enriches the context — from host definitions through user enumeration to domain-specific requirements.

Context-Aware Aspects

Aspects are composable bundles of cross-class Nix configs. They inspect context to produce conditional, parametric configurations — and are activated by a matching context.

Data flows through a declarative pipeline. You declare the entities (data) that exists in your universe, Den transforms them into progressively richer contexts to which aspects are attached, providing configuration for each context:

graph LR
  H["den.ctx.host {host}"] --> U["den.ctx.user {host, user} (for each user)"]
  U --> HM["aspect provides homeManager/hjeim class"]
  H --> OS["aspect provides nixos/darwin class"]

Each stage of the pipeline is a context type defined in den.ctx. Context types declare how to find aspects, how to transform into other contexts, and which parametric includes to activate.

Aspects are composable bundles of multi-class Nix modules that inspect their context parameters to decide what to produce. A function taking { host, ... } only runs when a host context exists. A function taking { host, user, ... } runs once per user on each host.

Functions that require parameters not present in the current context are not included. Den introduces pattern matching on context shape.

# Use Den API -- Build the dependencies graph for NixOS hosts
aspect = den.ctx.host { host = den.hosts.x86_64-linux.igloo; };
# Use flake-aspects API -- We enter the NixOS domain by resolving for the "nixos" class.
nixosModule = aspect.resolve { class = "nixos"; };
# Use NixOS API -- Instantiate using nixosSystem with the resolved module.
nixosConfigurations.igloo = lib.nixosSystem { modules = [ nixosModule ]; };

This same pattern works for any class — create your own context transformation graphs and replace "nixos" with "darwin", "systemManager", "terranix" or any custom class name.

No Lock-in

Works with flakes, without flakes, with flake-parts, or standalone. Den plays well with your existing Nix choices. And integrates with your existing infra.

Sharable Aspects

Re-usablity is one of the goals of Den. Allowing people to create truly-generic configuration modules. Namespaces let you publish and consume aspect libraries across repositories and flakes.

# use in flake-parts or any lib.evalModules where den.nixModule is imported
{ den, ... }: {
# declare your hosts, users and homes
den.x86_64-linux.hosts.igloo.users.tux = { };
# attach configurations via aspects
den.igloo.nixos.networking.hostName = "warm-home";
# user aspects can configure its home and host environment
den.tux.homeManager = { pkgs, ... }: { home.packages = [ pkgs.cowsay ]; };
den.tux.nixos.users.users.tux.desscription = "cute pinguin";
# include other re-usable aspects of yours or den batteries
den.tux.includes = [ (den.provides.user-shell "fish") ];
# generic config for all hosts, users, homes.
den.default.nixos.system.stateVersion = "25.11";
den.default.homeManager.home.stateVersion = "25.11";
den.default.includes [ den._.inputs' ];
}

Batteries Included

Opt-in aspects for common tasks: define-user, primary-user, user-shell, unfree packages, import-tree, and more.

Community

Share configurations through namespaces. Real-world setups and a growing ecosystem at denful (wip).

Feel free to to explore the codebase, particularly our included batteries and tests that serve as examples.

Contribute Community Sponsor