Skip to content

Context-aware Dendritic Nix

Aspect-oriented, context-driven Nix configurations

Den takes the Dendritic pattern to a whole new level, and I cannot imagine going back.
@adda - Very early Den adopter after using Dendritic flake-parts and Unify.

I’m super impressed with den so far, I’m excited to try out some new patterns that Unify couldn’t easily do.
@quasigod - Unify dendritic-framework author on adopting Den. [repo]

Massive work you did here!
@drupol - Author of “Flipping the Configuration Matrix” Dendritic blog post. [repo]

Thanks for the awesome library and the support for non-flakes… it’s positively brilliant!. I really hope this gets wider adoption.
@vczf - At den matrix channel.

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

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

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

Den uses a Dendritic Nix configuration model. Features are organized using flake-aspects — composable attrsets with per-class configurations and a dependency graph (provides/includes). Den’s context pipeline determines which aspects apply to which targets collecting the configurations they contribute to each context transformation stage, ultimately producing a single, unified system configuration.

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"]
flowchart BT
  subgraph "**den.aspects.dev-tools**"
    n["nixos"]
    h["homeManager"]
    d["darwin"]
  end
  n --> server["server (NixOS)"]
  n --> laptop["laptop (NixOS)"]
  d --> mac["mac (Darwin)"]
  h --> laptop
  h --> mac
  h --> standalone["alice (standalone HM)"]

Any Nix Configuration Class

NixOS, Darwin, system-manager, Terraform, or custom classes

Den works with anything configurable through Nix modules and any topology you can describe with Nix data and function transformations.

No Lock-in

Works with flake-parts, without flake-parts, or without flakes at all.

Den never uses lib.evalModules directly, but provides APIs and modules for use with your favorite Nix module system.

Sharable Aspects

Namespaces let you publish and consume aspect libraries across flakes or non-flakes.

Den is social, trying to bring re-usability across stable and unstable Nix boundaries. No Flakes mandated.

The following three lines is how a NixOS configuration is built. The very same process can be used for other Nix configuration domains outside of NixOS.

# Use Den API -- Context transformations happen here, nothing is configured yet.
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 ]; };

Built on top of den.lib, Den provides a framework with ready-made facilities for NixOS/nix-Darwin/homes configurations.

flowchart LR
  Schema["den.hosts / den.homes"] --> Ctx["den.ctx pipeline"]
  Aspects["den.aspects"] --> Ctx
  Batteries["den.provides"] --> Ctx
  Ctx --> Resolve["Resolution"]
  Resolve --> Out["nixos / darwin / homeConfigurations"]
  1. Schemaden.hosts and den.homes declare machines, users, and their properties with den.base modules and extensible freeform types.
  2. Aspectsden.aspects.* bundles per-class configs (nixos, darwin, homeManager, or any custom class) with .includes and .provides forming a DAG.
  3. Context pipelineden.ctx transforms schema entries into context pairs ({host}, {host, user}, {home}), walking into.* transitions for derived contexts like hm-host, hm-user, wsl-host or any other custom context stage.
  4. Resolution — Parametric dispatch via __functor argument introspection. Functions receive only contexts whose shape matches their parameters.
  5. Output — Each host/home is instantiated via nixpkgs.lib.nixosSystem, darwin.lib.darwinSystem, or home-manager.lib.homeManagerConfiguration.
Learn More

Star History Chart

Contribute Community Sponsor