ADR-0004 — Self-contained output

Every diagram inlines its styles, runtime, and icons, and makes zero network requests when opened.

Status: accepted

Built diagrams are fully self-contained. Styles, the runtime client, and the icon sprites actually used are inlined; external URLs are stripped at build time; no CDN, no web fonts, no telemetry, no analytics. Opening a diagram makes no network requests at all.

Why

The audience for a network diagram is often on the wrong side of a boundary: an air-gapped operations network, a customer site with no internet, a laptop on a plane, a change-review meeting in a basement. A diagram that needs a CDN is a diagram that fails exactly when someone is trying to fix an outage.

It also removes an entire class of decay. A diagram built today opens identically in five years because nothing it depends on can go away.

Consequences

No framework dependencies in the viewer, ever. The chrome is shadcn/ui ported to vanilla CSS and TypeScript rather than installed as components, because framework weight taxes every exported file. A proposal to add a React table library was rejected on these grounds. Porting means taking the upstream source's literal token values and metrics — approximating from memory produced visibly worse results.

The runtime has a budget. It sits around 20 KB. Every feature is weighed against that.

Author-supplied markup must be sanitized, not trusted — see ADR-0003. An externally-referencing logo would silently break the guarantee, so those references don't survive the build.

Only the icons a topology uses are embedded. A diagram with 12 distinct icons carries 12 sprite definitions, not the 2,850-icon catalog.

Inline styles and inline script are required. On a host with a strict Content Security Policy that forbids inline script, the single-file shape won't run. The multi-page site shape is the workaround — its runtime and styles are separate files under assets/ that a hash- or nonce-based policy can handle.

Large diagrams are large files. Everything travels together; that's the trade.

Considered and rejected

Shared assets across diagrams (one runtime.js, many HTML files). Rejected for the single-file shape — it breaks "email someone one file". It is how the multi-page site shape works, because a site is already a directory.

A CDN-hosted runtime. Rejected outright: fails offline, adds a dependency that can disappear, and makes the diagram phone home.