diagrams-js
Version:
A TypeScript port of the diagrams Python library for drawing cloud system architecture diagrams as code
267 lines (207 loc) • 6 kB
Markdown
---
name: diagrams-js/json-serialization
description: >
JSON export and import for diagrams. Serialize diagrams to JSON for cloud architecture provisioning,
infrastructure-as-code integration, and tool interoperability. Import JSON with automatic icon resolution.
type: core
library: diagrams-js
library_version: "0.5.0"
requires:
- diagrams-js/getting-started
- diagrams-js/provider-nodes
sources:
- "hatemhosny/diagrams-js:docs/docs/guides/json-serialization.mdx"
- "hatemhosny/diagrams-js:src/json.ts"
---
This skill builds on diagrams-js/getting-started and diagrams-js/provider-nodes. Read them first for foundational concepts.
# diagrams-js — JSON Serialization
Export diagrams to JSON format and import them back. Enables cloud architecture provisioning, infrastructure-as-code integration, version control, and tool interoperability. SVG output also supports round-trip serialization via embedded metadata.
## Setup
```typescript
import { Diagram } from "diagrams-js";
import { EC2 } from "diagrams-js/aws/compute";
const diagram = Diagram("My Architecture");
diagram.add(EC2("Server"));
// Export to JSON
const json = diagram.toJSON();
```
## Core Patterns
### Export to JSON
```typescript
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);
// Serialize to JSON
const json = diagram.toJSON();
// Save to file
import { writeFileSync } from "fs";
writeFileSync("diagram.json", JSON.stringify(json, null, 2));
```
### Import from JSON
```typescript
import { Diagram } from "diagrams-js";
const json = {
name: "My Architecture",
nodes: [
{
id: "web",
label: "Web Server",
provider: "aws",
service: "compute",
type: "EC2",
},
{
id: "db",
label: "Database",
provider: "aws",
service: "database",
type: "RDS",
},
],
edges: [{ from: "web", to: "db", label: "SQL" }],
};
const diagram = await Diagram.fromJSON(json);
const svg = await diagram.render();
```
### Import from JSON String
```typescript
const jsonString = readFileSync("diagram.json", "utf8");
const diagram = await Diagram.fromJSON(jsonString);
```
### JSON Structure
```json
{
"$schema": "https://diagrams-js.hatemhosny.dev/schema/diagram.json",
"name": "Architecture",
"direction": "TB",
"theme": "pastel",
"nodes": [
{
"id": "n1",
"label": "Web Server",
"provider": "aws",
"service": "compute",
"type": "EC2"
}
],
"edges": [
{
"from": "n1",
"to": "n2",
"label": "HTTPS",
"direction": "forward"
}
],
"clusters": [
{
"label": "Public Subnet",
"nodes": ["n1"],
"clusters": []
}
]
}
```
### Infrastructure as Code Integration
Generate diagrams from infrastructure definitions:
```typescript
// Terraform/CDK/pulumi state
const infrastructure = {
resources: [
{ type: "aws_instance", name: "web", subnet: "public" },
{ type: "aws_db_instance", name: "db", subnet: "private" },
],
};
// Convert to diagram JSON
const json = {
name: "Infrastructure",
nodes: infrastructure.resources.map((r) => ({
id: r.name,
label: r.name,
provider: "aws",
type: getService(r.type),
resource: getResourceType(r.type),
})),
};
const diagram = await Diagram.fromJSON(json);
await diagram.save("infrastructure.svg");
```
### Custom Providers Override
Override or supplement providers when importing:
```typescript
import { EC2, Lambda } from "diagrams-js/aws/compute";
const diagram = await Diagram.fromJSON(json, {
providers: [{ EC2, Lambda }],
});
```
## Common Mistakes
### CRITICAL Forgetting to await Diagram.fromJSON()
Wrong:
```typescript
const diagram = Diagram.fromJSON(json); // Missing await
const svg = await diagram.render(); // Error: diagram is Promise
```
Correct:
```typescript
const diagram = await Diagram.fromJSON(json);
const svg = await diagram.render();
```
`Diagram.fromJSON()` is async because it dynamically loads provider modules.
Source: source code - json.ts `fromJSON` returns Promise
### HIGH Missing required 'nodes' array
Wrong:
```typescript
const diagram = await Diagram.fromJSON({ name: "Test" });
// Throws: Invalid diagram JSON: 'nodes' array is required
```
Correct:
```typescript
const diagram = await Diagram.fromJSON({
name: "Test",
nodes: [], // Required, even if empty
});
```
Source: source code - json.ts validation
### MEDIUM Assuming iconUrl is required for icons
Wrong:
```typescript
const json = {
nodes: [{ id: "web", label: "Server", iconUrl: "data:image/png;base64,..." }],
};
// Works but embeds large data URLs
```
Correct:
```typescript
const json = {
nodes: [
{
id: "web",
label: "Server",
provider: "aws",
service: "compute",
type: "EC2",
},
],
};
// Icons resolved from provider/type/resource - clean JSON
```
Use provider/type/resource fields for automatic icon resolution. Avoid embedding icon data URLs unless using Custom nodes.
Source: source code - provider-loader.ts dynamic imports
## SVG Serialization (Alternative)
In addition to JSON, diagrams can be serialized through SVG. Every SVG produced by `diagram.render()` automatically embeds the full diagram metadata:
```typescript
const diagram = Diagram("Web Architecture");
diagram.add(EC2("Web Server"));
// SVG contains embedded metadata by default
const svg = await diagram.render();
// Re-import directly from SVG
const restored = await Diagram.fromSVG(svg);
```
Use SVG serialization when you want a single file that is both a visual diagram and an editable data source. Use `embedData: false` to generate a clean SVG without metadata.
## See also
- diagrams-js/rendering-export — Output formats and rendering
- diagrams-js/provider-nodes — Using cloud provider nodes
- diagrams-js/diagram-configuration — Diagram options and themes