Skip to content

diagrams-js

A TypeScript port of the diagrams Python library for drawing cloud system architecture diagrams as code

diagrams-js/svg-serialization

core
266 linesSource

SVG export and import for diagrams. Render diagrams to SVG with embedded metadata for round-trip serialization. Import previously exported SVG images back into editable diagrams. Alternative to JSON serialization with self-contained visual + data format.

This skill builds on diagrams-js/getting-started and diagrams-js/provider-nodes. Read them first for foundational concepts.

diagrams-js — SVG Serialization

Export diagrams to SVG format with embedded metadata and import them back. SVG serves as both a visual image and a self-contained data format, enabling round-trip editing without separate JSON files.

Setup

ts
import { Diagram } from "diagrams-js";
import { EC2 } from "diagrams-js/aws/compute";

const diagram = Diagram("My Architecture");
diagram.add(EC2("Server"));

// Render to SVG (includes embedded metadata by default)
const svg = await diagram.render();

Core Patterns

Export to SVG

ts
const diagram = Diagram("Web Architecture", {
  direction: "TB",
  theme: "pastel",
});

const web = diagram.add(EC2("Web Server"));
const db = diagram.add(RDS("Database"));
web.to(db);

// Render to SVG with embedded metadata
const svg = await diagram.render();

// Or use the explicit SVG exporter
const svg2 = await diagram.export("svg");

// Save to file
await diagram.save("architecture.svg");

Import from SVG

Restore a diagram from an SVG string using the static Diagram.fromSVG() method:

ts
import { Diagram } from "diagrams-js";

const svg = await fs.readFile("diagram.svg", "utf8");

// Restore the full diagram with all nodes, edges, and options
const diagram = await Diagram.fromSVG(svg);
const restoredSvg = await diagram.render();

Merge SVG into Existing Diagram

Import an SVG into an existing diagram via the plugin system:

ts
const diagram = Diagram("Merged Architecture");
await diagram.import(svgString, "svg");

SVG Data Attributes

The embedded metadata includes:

  • data-diagram-json (root <svg>): Base64-encoded full diagram JSON
  • data-diagram-version: Format version for compatibility
  • data-node-id, data-node-label: Per-node identifiers
  • data-node-provider, data-node-type, data-node-resource: Provider metadata
  • data-node-metadata: Base64-encoded custom metadata
  • data-cluster-label, data-cluster-nodes: Cluster information
  • data-edge-from, data-edge-to, data-edge-label: Edge information

These attributes enable DOM querying and third-party tooling.

Custom Classes and Data Attributes

Nodes, edges, and clusters can have custom CSS classes and data attributes injected into the SVG:

ts
const server = diagram.add(
  Node("Server", {
    className: "highlight",
    dataAttrs: { team: "backend", env: "prod" },
  }),
);

web.to(
  Edge({
    className: "critical",
    dataAttrs: { latency: "50ms" },
  }),
  db,
);

const cluster = diagram.cluster("VPC", {
  className: "production",
  dataAttrs: { region: "us-east-1" },
});

Injected SVG output:

html
<g class="node highlight" data-node-id="Server" data-team="backend" data-env="prod">...</g>
<g
  id="diagram_edge_0"
  class="edge critical"
  data-edge-from="web"
  data-edge-to="db"
  data-latency="50ms"
  >...</g
>
<g class="cluster production" data-cluster-label="VPC" data-region="us-east-1">...</g>

Access elements after rendering with getElement():

ts
const svg = await diagram.render();
document.body.innerHTML = svg;

server.getElement()?.addEventListener("click", handler);
edge.getElement()?.classList.add("hovered");
cluster.getElement()?.setAttribute("data-active", "true");

Clean SVG Without Metadata

To generate an SVG without embedded data:

ts
const cleanSvg = await diagram.render({ embedData: false });

This is useful when:

  • Distributing diagrams to external parties
  • Embedding in contexts where smaller file size matters
  • Publishing to documentation where metadata is unnecessary

Round-trip Consistency

SVG serialization preserves all diagram data:

ts
const original = Diagram("Test", { direction: "TB", theme: "blues" });
original.add(EC2("Server", { nodeId: "srv" }));
original.cluster("VPC").add(EC2("Web"));

// Export as SVG
const svg = await original.render();

// Import back
const restored = await Diagram.fromSVG(svg);

// Verify equivalence
const json1 = original.toJSON();
const json2 = restored.toJSON();
// json1 === json2

Comparison: JSON vs SVG Serialization

FeatureJSONSVG
Human-readableYesPartial (markup)
Visual previewNoYes (it's the image)
File sizeSmallLarger (contains image)
DOM queryableNoYes (data attributes)
Round-tripYesYes
Best forVersion control, APIsDistribution, documentation

Common Mistakes

CRITICAL Trying to import plain SVG without embedded data

Wrong:

ts
const plainSvg = `<svg xmlns="http://www.w3.org/2000/svg"><text>Hello</text></svg>`;
const diagram = await Diagram.fromSVG(plainSvg);
// Throws: Invalid diagram SVG: missing or corrupted embedded diagram data

Correct:

ts
// Only SVGs exported/rendered by diagrams-js can be imported
const svg = await diagram.render();
const restored = await Diagram.fromSVG(svg);

Source: source code - svg.ts extractDiagramData validation

HIGH Assuming embedData defaults to false

Wrong:

ts
const svg = await diagram.render();
// Surprised that SVG contains visible data attributes?
// embedData defaults to true

Correct:

ts
// Default behavior: embed metadata
const svg = await diagram.render(); // Contains data-diagram-json

// Opt-out when needed
const clean = await diagram.render({ embedData: false });

Source: source code - Diagram.ts render() embedData check

MEDIUM Using diagram.export("svg") expecting different output from render()

Wrong:

ts
const rendered = await diagram.render();
const exported = await diagram.export("svg");
// These are identical; export just calls render({ format: "svg" })

Correct:

ts
// Both produce the same SVG with embedded metadata
const svg = await diagram.render();
// Use render() directly; export is a convenience for plugin consistency

Source: source code - svg.ts exporter implementation

See also

  • diagrams-js/json-serialization — JSON export/import guide
  • diagrams-js/rendering-export — Output formats and rendering options
  • diagrams-js/diagrams-js-plugin-system — Plugin architecture