Skip to content

Diagrams

The diag library lets you visualize how Den resolves aspects — which aspects include which, how policies fan out, which classes each aspect contributes to. It transforms structured trace data from the effects pipeline into a format-agnostic graph Intermediate Representation (Graph IR), applies filters and reshapes, then renders into Mermaid, GraphViz DOT, PlantUML, C4, and other formats.

Every diagram passes through four stages:

flowchart LR
    A[Trace capture] --> B[Graph construction]
    B --> C[Filtering]
    C --> D[Rendering]
  1. Trace capture — collect structuredTrace entries from aspect resolution.
  2. Graph construction — build format-agnostic IR (nodes, edges, stages, stage transitions).
  3. Filtering — prune, fold, and reshape the IR (user-declared-only, class slices, adapters-only, etc.).
  4. Rendering — emit diagram strings in the target format.

The simplest usage renders a host’s full aspect graph as Mermaid:

diag.toMermaid (diag.hostContext { inherit host; })

Add a filter for a coarser overview:

diag.toMermaid (diag.graph.simplified (diag.hostContext { inherit host; }))

Or slice to a single class:

diag.toMermaid (diag.graph.classSlice "nixos" (diag.hostContext { inherit host; }))

Three wrappers build graph IR from common entity kinds without manually calling den.lib.resolveStage:

  • hostContext { host; classes?; direction?; } — resolves from the host root. Defaults to ["nixos" "homeManager" "user"] plus any user-declared classes.
  • userContext { host; user; classes?; direction?; } — resolves from the user root. Defaults to ["homeManager" "user"].
  • homeContext { home; classes?; direction?; } — resolves from a standalone home. Defaults to ["homeManager"].

For fully custom entities, use the generic context directly:

root = den.lib.resolveStage "user" { inherit host user; };
g = diag.context { inherit root; name = user.name; classes = [ "homeManager" ]; };

The graph IR is purely structural — all visual decisions happen at filter and render time. Filters compose: pipe one into another to narrow the view.

Key filters under diag.graph:

FilterEffect
simplifiedCoarse overview: folds providers and flattens stages
userDeclaredOnlyOnly aspects with a class assignment
filterUserAspectsRemoves wrapper/internal nodes
classSlice "nixos"Ancestor closure of aspects in one class
adaptersOnlyAdapter nodes and their neighbors
aspectsOnlyAspect-include edges only (no context/provider nodes)
providersOnlyProvider tree
contextOnlyContext hierarchy
RendererFormatUse case
toMermaidMermaid flowchartEmbed in docs, GitHub
toDotGraphViz DOTLarge graphs, PDF export
toPlantUMLPlantUMLUML-style diagrams
toSequenceMermaidMermaid sequenceStage resolution order
toC4ContextC4 model (PlantUML)Architecture overviews
toC4ComponentMermaidC4 model (Mermaid)Architecture overviews in Mermaid
toSankeyMermaidMermaid sankeyInclusion depth flow
toTreemapMermaidMermaid treemapAspect tree structure
toMindmapMermaidMermaid mindmapInclusion hierarchy
toStateMermaidMermaid state diagramStage state transitions
toJSONJSONMachine consumption

Every renderer has a *With variant (e.g. toMermaidWith) that accepts theme and config overrides. The renderers constructor builds a complete set with shared settings:

render = diag.renderers { inherit theme; mermaidConfig = { layout = "elk"; }; };
render.toMermaid graph

Diagrams support base16 color schemes via themeFromBase16:

theme = diag.themeFromBase16 { inherit pkgs; scheme = "catppuccin-mocha"; };

Pass the theme to renderers or individual *With functions. The library provides defaultTheme as a fallback.

diag.fleet.of builds a fleet-wide graph across all hosts in a flake:

fleetData = diag.fleet.of { flakeName = "my-fleet"; };

Fleet graphs feed into fleet-specific renderers like toFleetSankeyMermaid, toFleetTreemapMermaid, and toFleetProviderMatrix.

For generating SVG derivations (e.g. for a docs site), use renderContext and export:

rc = diag.renderContext { inherit pkgs theme; mermaidConfig = elkCfg; };
entries = diag.export.ofViews { inherit pkgs rc; } allHosts hostViewDefs fleetData fleetViewDefs;

The renderContext bundles pre-configured renderers, SVG builder functions, and standard view definitions (rc.views.host, rc.views.fleet, etc.) into a single record that templates consume.

  • Aspects — how aspects compose
  • Entities — the entity kinds that diagrams trace
  • Policies — policy fan-out visible in diagram views
Contribute Community Sponsor