Skip to content

Themes

Theme the diagram as a system, not as a collection of individually colored boxes. Start from the built-in light or dark tokens, change a small semantic palette, and preserve contrast.

The built-in light and dark palettes are the product default. Register a theme when the destination needs its own paper, ink, and chrome — then opt into rounded corners and shadows on the render call (or in a source render block).

Built-in theme — follows this page

Diagram with 5 nodes and 4 edges CheckoutApplicationWeb appAPICheckoutOrdersStripePOST /orderswriteauthorize

Registered acme-paper — rounded corners, shadows, snapshot

Diagram with 5 nodes and 4 edges CheckoutApplicationWeb appAPICheckoutOrdersStripePOST /orderswriteauthorize

The paper example snapshots resolved tokens, so toggling the docs theme leaves it cream. Use that when SVG leaves your site. Leave snapshotTheme: false (and theme: "auto") when an inline host should follow html[data-theme].

example.ts
await KDiagram.renderToSvg(source, {
theme: "light",
snapshotTheme: true,
});
  • snapshotTheme: true resolves tokens into a self-contained SVG for files, wikis, and external images.
  • snapshotTheme: false leaves CSS variables available for an inline or interactive host to override.
  • theme: "auto" (with snapshotTheme: false) follows html[data-theme] on inline SVG and interactive hosts. Stamp theme: "light" or "dark" when the diagram must stay on one side.

This choice is about delivery. A registered theme does not automatically cross an <img> boundary.

Spread a built-in token set, then override the roles that should look like the brand. The diagrams above use the same source; the paper side is this registration plus render chrome:

diagram.kdiagram
diagram "Checkout" {
direction LR
presentation {
title: auto
groupAccent: true
}
web: client "Web app" { icon: monitor }
group app "Application" {
api: gateway "API" { icon: waypoints }
checkout: service "Checkout" { icon: shopping-cart }
}
orders: database "Orders" { icon: database }
stripe: external "Stripe" { icon: simple-icons:stripe }
web -> api "POST /orders"
api -> checkout
checkout -> orders "write"
checkout -> stripe "authorize"
}
example.ts
import { getThemeTokens, registerTheme, KDiagram } from "@kekonic/diagrams";
registerTheme("acme-paper", {
...getThemeTokens("light"),
"--kd-bg": "#f4efe6",
"--kd-surface": "#fffaf3",
"--kd-text": "#1c1917",
"--kd-muted": "#6b6358",
"--kd-border": "#d4c4ae",
"--kd-edge": "#7a7166",
"--kd-accent": "#b45309",
"--kd-user-fill": "#fde8d8",
"--kd-user-stroke": "#c2410c",
"--kd-service-fill": "#f3e4c8",
"--kd-service-stroke": "#b45309",
"--kd-data-fill": "#e4efe6",
"--kd-data-stroke": "#3f6f4e",
"--kd-external-fill": "#f6f1ea",
"--kd-external-stroke": "#78716c",
"--kd-group-fill": "rgba(180, 83, 9, 0.08)",
"--kd-group-stroke": "rgba(180, 83, 9, 0.38)",
"--kd-node-shadow": "rgba(28, 25, 23, 0.18)",
});
const result = await KDiagram.renderToSvg(source, {
theme: "acme-paper",
snapshotTheme: true,
shadows: true,
roundedCorners: true,
});

shadows and roundedCorners default to off. The same flags exist in a source render block; API options override source policy. Spreading a built-in token set protects you when new tokens are introduced. Override semantic roles, not every renderer detail. Register a dark sibling if the host toggles theme and the brand should follow it.

Role Common tokens
Canvas and type --kd-bg, --kd-surface, --kd-text, --kd-muted
Structure --kd-border, --kd-edge, --kd-edge-label-bg
Semantics --kd-accent, --kd-success, --kd-warning, --kd-danger
Architecture --kd-service-fill, --kd-service-stroke, --kd-data-fill, --kd-data-stroke
Boundaries --kd-group-fill, --kd-group-stroke
Sequence --kd-sequence-lifeline, --kd-sequence-activation-fill, --kd-sequence-fragment-stroke

The complete token object is exported as ThemeTokens, so editors can show the token contract.

Use a source style when one node or fragment has a meaning the global theme should not absorb:

diagram.kdiagram
style degraded {
--node-fill: #2a1f08
--node-stroke: #d69e2e
}
cache: cache "Redis" {
styles: [degraded]
}

Built-in semantic styles include success, warning, danger, error, muted, and info. Prefer them when they match the meaning. A diagram with many bespoke colors stops behaving like a theme and starts behaving like a legend no one was given.

Test the final destination in both themes. Check text against fills, edge labels against the canvas, and semantic colors without relying on hue alone. Kind, operator, label, and shape should continue to carry meaning when color perception or printing removes part of the palette.