Esc

comark-diagrams

Diagrams

Write a diagram in a fenced block and get it as SVG in the page, drawn while parsing by a Kroki server, with no script.

Playground
How a sighting reaches the map

A diagram in a review shows what changed in a flow or a schema faster than prose. The plugin sends each diagram's source to a Kroki server while parsing and puts the SVG it draws in the page, after taking out anything that could run. The diagram's source leaves your machine: it goes to kroki.io unless you run your own Kroki.

Fence Drawn by
```plantuml PlantUML: sequence, class, state, and other UML diagrams
```graphviz or ```dot Graphviz: graphs in the DOT language
```d2 D2: boxes and arrows in a short syntax
```dbml DBML: database tables and their relations
```goat GoAT: ASCII art as lines and arrows
```svgbob Svgbob: ASCII art as lines and arrows

Every other fence stays code.

A title in brackets after the language goes under the diagram and names it for screen readers:

```d2 [Login flow]
user -> api -> db
```
md

A diagram Kroki can't draw stays as code, and the plugin adds a sentence to meta.issues, as Validation describes, with the first line of the tool's error. So does a diagram drawn while the server can't be reached:

The ```dot fence 2: Kroki couldn't draw it: Error: <stdin>: syntax error in line 1 near 'a'. Fix the diagram's source.
The ```d2 fence 1: couldn't reach the Kroki server at https://kroki.io (fetch failed). Check `server`, or build again.
txt

A diagram that failed is drawn again on the next parse. Each issue has its own rule in Doctor.

The plugin keeps the drawing and drops what could run: scripts, event handlers such as onclick, embedded HTML (foreignObject), animations, links that aren't to a web page or within the drawing, and @import in its styles. The XML prolog, doctype, and comments go too.

Each diagram's source is sent to the Kroki server in a POST request while the document is parsed. With the default server, that's https://kroki.io, a free public service run by the Kroki project. Don't send it a diagram you wouldn't post publicly: an internal architecture, a schema with sensitive names, anything under an NDA.

The readers of the page never contact Kroki. They get the SVG inline.

Kroki is open source and runs from one container. The core image draws Graphviz, PlantUML, D2, DBML, GoAT, and Svgbob:

docker run -d -p 8000:8000 yuzutech/kroki

Then point the plugin at it:

diagrams({ server: "http://localhost:8000" });
ts

In CI, run it as a service container next to the build. See Kroki's install guide for other options.

The tools draw dark lines on white, so each diagram sits on a white card on any page, in its own frame. Set --cdg-canvas to change it, as Theme shows. A diagram wider than the page scrolls sideways inside its card.

Some tools, such as D2, put a <style> in their SVG, scoped to the drawing's own ids. Inline SVG shares the page's styles, so the plugin keeps those and only drops @import. Theming the diagram itself is up to the tool's own syntax.

Options go under diagrams in comarkUi(), or to diagrams() when you use it alone.

Parsing waits for each diagram from the Kroki server, so the page needs no script and no request when it's read. Every diagram is drawn once per process, so a site that builds many pages asks for each one once.

The diagram's source is sent to https://kroki.io by default. To keep it private, run your own Kroki and pass its address as server, as Run your own Kroki describes:

diagrams({ server: "http://localhost:8000" });
ts

Pass draw: false to leave every diagram as code and send nothing, such as in a linter.

comark-ui brings comark-diagrams and registers it. To use it alone, install it and pass the renderer's components:

pnpm add comark @comark/html comark-diagrams
import { createHtmlRenderer } from "@comark/html";
import diagrams, { components } from "comark-diagrams/html";

const render = createHtmlRenderer({ plugins: [diagrams()], components });
ts

For Vue, React, or Svelte, import from comark-diagrams/vue, comark-diagrams/react, or comark-diagrams/svelte; the components add the styles when they mount. Import comark-diagrams/style.css with your styles so a server-rendered page doesn't shift. Renderers covers using it with other plugins.

Each diagram sits on a card in a 1px frame with its title under it. The card stays white on a dark page, since diagram tools draw dark lines on white whatever the page's theme. The rules sit in a comark CSS layer, so any plain rule of your own wins.

Diagrams read these shared tokens:

Token Used for
--comark-muted The title under a diagram
--comark-border The card's frame
--comark-radius The card's corners
--comark-font The title
Variable Default Used for
--cdg-canvas #fff The card behind a diagram. Set it on .cdg for a tool whose theme draws light lines.

A diagram is figure.cdg, with data-type set to its Kroki type, such as d2 or graphviz. The drawing sits in .cdg-svg, and its title in figcaption.