IInbox
Composed

Diagram

Server-rendered technical diagrams in plain SVG — orthogonal routing, boundaries, flow, and a text description that carries the graph.

Architecture diagrams for the kind of product that needs them. Plain SVG, rendered on the server, no runtime. Live at /lab/diagram.

Installation

npx shadcn@latest add https://ui.whoisroktim.lol/r/diagram.json

Data, not children

<Diagram
  width={880}
  height={260}
  caption="A browser request reaches the edge…"
  groups={[{ x: 236, y: 14, w: 430, h: 232, label: "Platform" }]}
  nodes={[
    { id: "client", x: 20, y: 100, label: "Browser", sub: "Next.js", kind: "client" },
    { id: "api", x: 268, y: 160, label: "API", sub: "Fluid", kind: "accent" },
  ]}
  edges={[{ from: "client", to: "api", label: "POST" }]}
/>

<Edge from="api" to="db" /> cannot route itself without knowing where both boxes are, and threading that through context to lay out an SVG is more machinery than the feature is worth. So edges name nodes by id, and a typo'd id drops that one edge rather than taking the whole diagram down.

Node kinds — service, store, client, external, accent — all resolve to token variables, so a diagram follows the theme.

Routing

The maths is in diagram-route.ts as pure functions, tested directly, because a diagram that is subtly wrong still looks like a diagram.

Sides come from the gap on each axis, not the distance between centres. Two boxes side by side but vertically offset have a larger centre-to-centre dy than you would expect; picking sides from that routes the edge top-to-bottom and sends it looping around the outside.

Paths begin and end on the box boundary, never at the centres. Route centre-to-centre and the arrowhead is buried inside the target — the single most common way a hand-rolled diagram looks wrong.

Corner radius is capped at half the shorter adjoining segment. A fixed radius on a short jog overshoots the corner and the line visibly doubles back.

Labels sit at the halfway point by length, not the middle index. The middle segment of an elbow is usually the shortest, so indexing drops the label on a corner. They also get a plate behind them, or the connector runs through the words.

Flow

flow marches the dashes along an edge, for anything carrying a stream. It is SMIL rather than a CSS animation so it still runs inside an SVG with role="img", and a prefers-reduced-motion rule stops it.

The description is not optional

Every diagram renders its edges as a screen-reader list beside the figure:

Browser connects to API, POST. API connects to Postgres, SQL.

alt text cannot carry a graph, and a diagram that explains an architecture to sighted readers and nothing to anyone else is half a diagram. The caption does double duty as aria-label and as the visible figure caption, so the two can never drift apart.