Skip to content

den.lib.capture & den-diagram

Diagram rendering is split across two packages:

  • den.lib.capture (in den) — runs the fx pipeline with tracing handlers, produces structured trace entries
  • den-diagram (separate repo) — graph IR, filters, renderers. Pure library, depends only on nixpkgs.lib

See Diagrams explanation for concepts and usage patterns.

Capture in den, render in den-diagram:

diagram = inputs.den-diagram.lib;
# 1. Capture
captured = den.lib.capture.captureWithPathsWith {
classes = [ "nixos" "homeManager" ];
root = den.lib.resolveEntity "host" { inherit host; };
ctx = { inherit host; };
};
# 2. Build graph IR
g = diagram.context {
entries = captured.entries;
ctxTrace = captured.ctxTrace;
name = host.name;
};
# 3. Render
diagram.toMermaid g

graph.build { entries, rootName, ctxTrace?, direction? }

Section titled “graph.build { entries, rootName, ctxTrace?, direction? }”

Core IR builder. Transforms a list of structured trace entries into a graph record containing nodes, edges, stages, stageEdges, rootId, rootName, and direction. This is the lowest-level constructor — convenience wrappers call it internally.

Thin wrapper around hostContext that strips auxiliary fields (rootAspect, pathSets, classes), returning a plain graph record.

graph.ofNamespace { name?, aspects?, direction?, filter? }

Section titled “graph.ofNamespace { name?, aspects?, direction?, filter? }”

Static namespace graph built from den.aspects declarations (no host resolution). Walks authored building blocks and their static inclusions. Useful for fleet-level views showing the full aspect catalogue.

All filters are available on the graph attrset (e.g., diagram.graph.aspectsOnly). Each takes a graph IR and returns a new graph IR.

FilterSignatureDescription
userDeclaredOnlygraph -> graphNodes with hasClass = true — user-authored aspects only
pipelineOnlygraph -> graphWrapper/plumbing nodes only — reveals resolution machinery
crossClassOnlygraph -> graphNodes contributing to 2+ classes — bridge aspects
orphansAndLeavesgraph -> graphNodes with no incoming edges (orphans) or no outgoing edges (leaves)
FilterSignatureDescription
classSlicestring -> graph -> graphAncestor closure from nodes active in the given class
neighborhoodOf(node -> bool) -> graph -> graphNodes matching predicate plus their direct neighbors
adaptersOnlygraph -> graphNodes with resolution handlers plus neighbors
parametricOnlygraph -> graphParametric aspects (isParametric = true) plus neighbors
FilterSignatureDescription
contextOnlygraph -> graphContext pipeline stages as nodes, aspect content discarded
aspectsOnlygraph -> graphUser aspects with context wrappers folded out, provider edges dropped
providersOnlygraph -> graphProvider hierarchy as a multi-level tree
providersResolvedgraph -> graphProviders alongside their resolved output nodes
decisionsViewgraph -> graphStructural decisions — excluded nodes grouped by adapter owner
FilterSignatureDescription
foldWrappersgraph -> graphRemove wrapper/context nodes, rewire edges to their children
foldProvidersgraph -> graphCollapse provider chains into single edges
flattenStagesgraph -> graphRemove stage subgraph grouping
FilterSignatureDescription
filterMeaningfulgraph -> graphDrop anonymous and definition-stub nodes
filterUserAspectsgraph -> graphfoldWrappers composed with filterMeaningful
simplifiedgraph -> graphfoldProviders + flattenStages + aspectsOnly
FunctionSignatureDescription
fanMetricsgraph -> [{ id, label, fanIn, fanOut, total, ... }]Fan-in/fan-out counts per node, sorted by total
diff{ a, b } -> graphMerge two graphs with origin tags ("a", "b", "both") on each node and edge
FilterSignatureDescription
hasAspectPresent{ class } -> graph -> graphNodes answering hasAspect = true for the given class (ancestor closure)
hasAspectForAnyClass[string] -> graph -> graphUnion of hasAspectPresent across multiple classes

Every renderer has two forms: toFoo uses the default theme and toFooWith { theme?, mermaidConfig? } accepts explicit options. All take graph -> string (or fleetData -> string for fleet renderers).

RendererFormatNotes
toMermaid / toMermaidWithMermaid flowchartPrimary renderer; supports ELK layout via mermaidConfig
toDot / toDotWithGraphviz DOTNo mermaidConfig option
toPlantUML / toPlantUMLWithPlantUMLNo mermaidConfig option
RendererFormatNotes
toSequenceMermaid / toSequenceMermaidWithMermaid sequenceStage sequence diagram
toSequenceMermaidExpanded / toSequenceMermaidExpandedWithMermaid sequenceExpanded with per-aspect detail
toPolicySequenceMermaid / toPolicySequenceMermaidWithMermaid sequencePolicy-level sequence
toStageEdgesMermaid / toStageEdgesMermaidWithMermaidStage topology edges
RendererFormatNotes
toC4Component / toC4ComponentWithPlantUML C4Component diagram
toC4Container / toC4ContainerWithPlantUML C4Container diagram
toC4Context / toC4ContextWithPlantUML C4Context diagram (fleet-level)
toC4ComponentMermaid / toC4ComponentMermaidWithMermaid C4Component diagram
toC4ContainerMermaid / toC4ContainerMermaidWithMermaid C4Container diagram
toC4ContextMermaid / toC4ContextMermaidWithMermaid C4Context diagram
RendererFormatNotes
toSankeyMermaid / toSankeyMermaidWithMermaid sankeyAspect flow
toFleetSankeyMermaid / toFleetSankeyMermaidWithMermaid sankeyFleet-wide flow
toFanMetricsSankey / toFanMetricsSankeyWithMermaid sankeyFan-in/fan-out metrics
RendererFormatNotes
toTreemapMermaid / toTreemapMermaidWithMermaidAspect treemap
toFleetTreemapMermaid / toFleetTreemapMermaidWithMermaidFleet-wide treemap
toFleetProviderMatrix / toFleetProviderMatrixWithMermaidProvider matrix across hosts
RendererFormatNotes
toMindmapMermaid / toMindmapMermaidWithMermaid mindmapAspect mindmap
toStateMermaid / toStateMermaidWithMermaid stateState diagram
toJSONJSONGraph IR serialized to JSON (no theme)

Factory that returns an attrset of all pre-configured renderers. Each key is a toFoo function with the given theme/config baked in. Includes toJSON.

Hard-coded github-light palette. No pkgs required — the library is usable without running any build-time tools.

Build a theme from a base16 palette. Converts the YAML scheme to JSON via yj at build time.

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

Build a theme from a raw palette attrset ({ base00, base01, ..., base0F }).

Low-level helper: returns the raw { base00, ..., base0F } palette without wrapping it in a theme record.

A theme record contains: palette, background, foreground, mutedForeground, nodeBg, nodeBorder, nodeText, clusterBg, clusterBorder, edgeColor, edgeText, labelBg, rootFill, rootStroke, rootText, excludedFill, excludedStroke, excludedText, replacedFill, replacedStroke, replacedText, and accentPool (list of 8 accent colors used by per-node color hashing).

Build fleet-wide data from a host registry. hosts is required (pass den.hosts); flakeName defaults to "den flake".

Returns:

FieldTypeDescription
flakeNamestringDisplay name for the fleet
hosts[{ name, description }]Host records (description is the system string)
users[{ name }]Deduplicated user records across all hosts
relations[{ from, to, label }]User-to-host edges labeled with class names
providerSubAspects[{ provider, subAspect, hostName }]Optional — callers pre-compute via den.lib.capture and pass in

renderContext { pkgs, theme?, mermaidConfig?, mermaidCli?, renderFonts?, fontFamily? }

Section titled “renderContext { pkgs, theme?, mermaidConfig?, mermaidCli?, renderFonts?, fontFamily? }”

Factory that builds a record carrying everything needed to render views. Wires up SVG infrastructure and pre-configured renderer sets.

Returns:

FieldDescription
renderRenderer set with default theme (no mermaidConfig)
renderDenseRenderer set with mermaidConfig applied
themeThe resolved theme record
viewsPre-built view definition sets (.core, .host, .user, .home, .fleet, .classViews)
mmdSourceToSvgbase -> source -> derivation — Mermaid source to SVG
pumlSourceToSvgbase -> source -> derivation — PlantUML source to SVG
rc = diagram.renderContext { inherit pkgs; mermaidConfig = { layout = "elk"; }; };
rendered = rc.render.toMermaid myGraph;

Utilities for turning view definitions into derivations, packages, and write scripts. Available under diagram.export.

entityEntries { pkgs, rc } { entity, name, dir, viewDefs, galleryDrv? }

Section titled “entityEntries { pkgs, rc } { entity, name, dir, viewDefs, galleryDrv? }”

Generate all derivation entries (markdown + SVG) for a single entity. entity must be a pre-computed graph.

fleetEntries { pkgs } { fleetData, viewDefs, galleryDrv? }

Section titled “fleetEntries { pkgs } { fleetData, viewDefs, galleryDrv? }”

Generate all derivation entries for fleet-level views.

entries -> attrset — Convert entry list to a { name = derivation; } attrset suitable for packages.

entries -> [{ path_, drv }] — Convert entries to file records.

mkGallery pkgs { name, dir, title, entries }

Section titled “mkGallery pkgs { name, dir, title, entries }”

Build a gallery markdown file embedding all SVG views for a directory.

mkWriteScript pkgs { entries, galleries?, readmeDrv?, destExpr?, scriptName? }

Section titled “mkWriteScript pkgs { entries, galleries?, readmeDrv?, destExpr?, scriptName? }”

Assemble a shell script that copies all entries and galleries to a target directory. Used by diagram templates to produce a write-diagrams package.

View definitions describe what to compute from a graph IR and how to present it. Each is a list of records with fields: view (identifier), title, altText, mdLang, svgInfix, svgFn, and compute (graph -> string).

Essential views shared by all entity kinds: aspect hierarchy, stage sequence, expanded stage sequence, policy sequence, provider tree, and IR JSON.

Optional extra views: context hierarchy, simplified, stage topology, providers resolved, adapter impact, structural decisions, and user-declared aspects.

views.host rc / views.user rc / views.home rc

Section titled “views.host rc / views.user rc / views.home rc”

Entity-specific view sets. Currently all return views.core rc.

Fleet-wide views: aspect namespace, fleet C4 context (PlantUML), and fleet provider matrix.

Dynamic per-class views. Generates a class-slice view for each class name in the list.

Capture functions that run the fx pipeline with tracing handlers. Available at den.lib.capture.

Capture structured trace entries for a single class. Returns a list of entries.

Capture entries for multiple classes, concatenated.

Returns { entries, pathsByClass, ctxTrace } — entries plus per-class path sets needed by presence filters.

captureWithPathsWith { classes, root, extraHandlers? }

Section titled “captureWithPathsWith { classes, root, extraHandlers? }”

Extended form accepting additional trace handlers.

Contribute Community Sponsor