SDK Reference
The Diagram class is the main interface for creating diagrams. All methods return element IDs that can be used with connect(), addGroup(), and editing methods.
Constructor
Section titled “Constructor”new Diagram(opts?)
Section titled “new Diagram(opts?)”Create a new diagram with optional configuration:
const d = new Diagram(); // defaultsconst d = new Diagram({ direction: "LR" }); // left-to-right layoutconst d = new Diagram({ theme: "sketch" }); // hand-drawn styleconst d = new Diagram({ type: "sequence" }); // sequence diagram modeConstructor options:
| Option | Type | Default | Description |
|---|---|---|---|
direction | "TB" | "LR" | "RL" | "BT" | "TB" | Layout direction (top-bottom, left-right, etc.) |
theme | "default" | "sketch" | "blueprint" | "minimal" | "default" | Visual theme preset |
type | "architecture" | "sequence" | "architecture" | Diagram type |
Themes
Section titled “Themes”setTheme(theme)
Section titled “setTheme(theme)”Set a theme preset that applies defaults to all subsequently added shapes.
d.setTheme("sketch"); // hand-drawn: hachure fill, roughness 2d.setTheme("blueprint"); // technical: clean lines, Cascadia fontd.setTheme("minimal"); // minimal: thin strokes, Helvetica, 90% opacityAvailable themes:
| Theme | Fill Style | Roughness | Stroke Width | Font | Opacity |
|---|---|---|---|---|---|
default | solid | — | — | Virgil | — |
sketch | hachure | 2 | — | Virgil | — |
blueprint | solid | 0 | 1 | Cascadia | — |
minimal | solid | 0 | 1 | Helvetica | 90 |
Per-node options always override theme defaults.
setDirection(direction)
Section titled “setDirection(direction)”Set the layout direction after construction.
d.setDirection("LR"); // switch to left-to-rightCreating Elements
Section titled “Creating Elements”addBox(label, opts?)
Section titled “addBox(label, opts?)”Add a rectangle element. Returns the element ID. Labels support \n for line breaks — the shape auto-sizes to fit.
const id = d.addBox("API Gateway", { row: 0, col: 1, color: "backend" });const id2 = d.addBox("Master DO\n(Single Writer)", { color: "storage" }); // multi-lineaddEllipse(label, opts?)
Section titled “addEllipse(label, opts?)”Add an ellipse element. Returns the element ID.
const id = d.addEllipse("Start", { row: 0, col: 0, color: "users" });addDiamond(label, opts?)
Section titled “addDiamond(label, opts?)”Add a diamond shape (for flowchart decisions). Returns the element ID.
const id = d.addDiamond("Is Valid?", { row: 1, col: 1, color: "orchestration" });addText(text, opts?)
Section titled “addText(text, opts?)”Add standalone text (no container). Returns the element ID.
const id = d.addText("System Overview", { x: 100, y: 50, fontSize: 24, fontFamily: 2, // Helvetica});Text options:
| Option | Type | Description |
|---|---|---|
x | number | Absolute x position |
y | number | Absolute y position |
fontSize | number | Font size (default 16) |
fontFamily | 1 | 2 | 3 | Virgil / Helvetica / Cascadia |
color | ColorPreset | Semantic color preset |
strokeColor | string | Hex color override |
addLine(points, opts?)
Section titled “addLine(points, opts?)”Add a line element. Returns the element ID.
const id = d.addLine([[0, 0], [200, 100]], { strokeColor: "#e03131", strokeWidth: 2, strokeStyle: "dashed",});Grouping
Section titled “Grouping”addGroup(label, children, opts?)
Section titled “addGroup(label, children, opts?)”Group elements with a dashed boundary. Returns the group ID.
const db = d.addBox("Postgres", { row: 1, col: 0, color: "database" });const cache = d.addBox("Redis", { row: 1, col: 1, color: "cache" });d.addGroup("Data Layer", [db, cache]);d.addGroup("VPC", [svc1, svc2], { padding: 50, strokeColor: "#e03131" });Group options:
| Option | Type | Default | Description |
|---|---|---|---|
padding | number | 30 | Pixels of padding around children |
strokeColor | string | #868e96 | Hex color for the group boundary |
strokeStyle | "solid" | "dashed" | "dotted" | "dashed" | Boundary line style |
opacity | number | 60 | Group boundary opacity (0-100) |
addFrame(name, children)
Section titled “addFrame(name, children)”Add a native Excalidraw frame container. Returns the frame ID.
const svc1 = d.addBox("Service A", { color: "backend" });const svc2 = d.addBox("Service B", { color: "backend" });d.addFrame("Microservices", [svc1, svc2]);removeGroup(id) / removeFrame(id)
Section titled “removeGroup(id) / removeFrame(id)”Remove a group or frame container. Children are kept.
Connections
Section titled “Connections”connect(from, to, label?, opts?)
Section titled “connect(from, to, label?, opts?)”Connect two elements with an arrow.
d.connect(api, db, "queries");d.connect(api, cache, "reads", { style: "dashed" });d.connect(a, b, "flow", { startArrowhead: "dot", endArrowhead: "triangle" });d.connect(a, b, "near source", { labelPosition: "start" });d.connect(a, b, "near target", { labelPosition: "end" });Editing Existing Diagrams
Section titled “Editing Existing Diagrams”Diagram.fromFile(path)
Section titled “Diagram.fromFile(path)”Load an existing .excalidraw file for modification.
const d = await Diagram.fromFile("diagram.excalidraw");findByLabel(label, opts?)
Section titled “findByLabel(label, opts?)”Find node IDs by label match. Substring match by default, exact with opts.exact.
const ids = d.findByLabel("API"); // substring matchconst ids = d.findByLabel("API", { exact: true }); // exact matchgetNodes()
Section titled “getNodes()”Get all node IDs.
const allNodes = d.getNodes();getEdges()
Section titled “getEdges()”Get all edges.
const edges = d.getEdges();// [{ from: "id1", to: "id2", label: "queries" }, ...]getNode(id)
Section titled “getNode(id)”Get properties of a specific node by ID.
const info = d.getNode(id);// → { label, type, width, height, backgroundColor, strokeColor, row, col }Returns undefined if the ID doesn’t exist.
updateNode(id, opts)
Section titled “updateNode(id, opts)”Update a node’s properties.
d.updateNode(ids[0], { label: "New API", color: "ai" });updateEdge(from, to, update, matchLabel?)
Section titled “updateEdge(from, to, update, matchLabel?)”Update an existing edge’s properties. Optional matchLabel disambiguates when there are multiple edges between the same nodes.
d.updateEdge(api, db, { label: "writes", style: "dashed" });removeNode(id)
Section titled “removeNode(id)”Remove a node and its connected edges.
d.removeNode(d.findByLabel("Old Service")[0]);removeEdge(from, to, label?)
Section titled “removeEdge(from, to, label?)”Remove an edge between two nodes. Optional label disambiguates multi-edges.
d.removeEdge(api, db, "queries");Sequence Diagrams
Section titled “Sequence Diagrams”Create sequence diagrams with actors and messages:
const d = new Diagram({ type: "sequence" });const client = d.addActor("Client");const api = d.addActor("API Server");const db = d.addActor("Database");
d.message(client, api, "POST /login");d.message(api, db, "SELECT user");d.message(db, api, "user record");d.message(api, client, "JWT token");
// Self-messagesd.message(api, api, "validate token");
return d.render();addActor(label, opts?)
Section titled “addActor(label, opts?)”Add a sequence diagram actor. Returns the actor ID. Uses the same ShapeOpts as addBox.
message(from, to, label?, opts?)
Section titled “message(from, to, label?, opts?)”Add a message between actors. Uses the same ConnectOpts as connect. Self-messages (same actor) render as rectangular loops.
Decompiler
Section titled “Decompiler”toCode(opts?)
Section titled “toCode(opts?)”Convert the current diagram state back to TypeScript SDK code. Produces compact, readable code that recreates the diagram — useful for debugging, sharing, and editing existing diagrams.
const code = d.toCode();// Returns TypeScript like:// const d = new Diagram();// const api = d.addBox("API Gateway", { row: 0, col: 1, color: "backend" });// ...
// With a file path for render output:const code = d.toCode({ path: "architecture.excalidraw" });Features:
- Reverse-maps hex colors back to named presets (
"#d0bfff"→"backend") - Generates camelCase variable names from labels
- Extracts shared styles when 3+ nodes share the same non-positional options
- Avoids JavaScript reserved words in variable names
A .drawmode.ts sidecar file containing toCode() output is automatically written alongside any file output from render().
Mermaid Import
Section titled “Mermaid Import”Diagram.fromMermaid(syntax)
Section titled “Diagram.fromMermaid(syntax)”Convert Mermaid syntax into a Diagram for further modification:
const d = Diagram.fromMermaid(` graph LR A[API Gateway] --> B[Auth Service] A --> C[Order Service] B --> D[(Database)]`);d.updateNode(d.findByLabel("API Gateway")[0], { color: "backend" });return d.render();Supported: graph TD/LR/RL/BT, node shapes ([], {}, (()), [()]), edges (-->, ---, -..->, ==>), edge labels (|label|), subgraphs, chained edges.
Rendering
Section titled “Rendering”render(opts?)
Section titled “render(opts?)”Render the diagram. Always return this from your code.
return d.render(); // default: excalidraw JSONreturn d.render({ format: "url" }); // shareable URLreturn d.render({ format: "excalidraw", path: "out.excalidraw" }); // write filereturn d.render({ format: "png", path: "out.png" }); // PNG imagereturn d.render({ format: "svg", path: "out.svg" }); // SVG markupreturn d.render({ format: ["excalidraw", "svg"] }); // both formats at onceRender options:
| Option | Type | Default | Description |
|---|---|---|---|
format | string | string[] | "excalidraw" | Output format(s). Pass an array for multiple outputs. |
path | string | — | Base file path (extensions derived per format) |
Return type (RenderResult):
| Field | Type | Description |
|---|---|---|
json | object | Raw Excalidraw JSON |
url | string? | excalidraw.com shareable link |
filePath | string? | Local file path if written |
filePaths | string[]? | All file paths written (multi-format) |
pngBase64 | string? | Base64-encoded PNG (format=“png”) |
svgString | string? | SVG markup string (format=“svg”) |
A .drawmode.ts sidecar file is always written alongside any file output, preserving the source code for future iteration.
Grid Layout
Section titled “Grid Layout”Nodes placed with row and col are positioned on a grid with these constants:
| Constant | Value | Description |
|---|---|---|
| Column spacing | 280px | Horizontal distance between columns |
| Row spacing | 220px | Vertical distance between rows |
| Base position | (100, 100) | Top-left starting position |
| Default shape width | 180px | Minimum width (auto-expands for long labels) |
| Default shape height | 80px | Height (+24px per additional \n line) |
For precise control, use x and y in ShapeOpts to bypass the grid entirely.
Type Reference
Section titled “Type Reference”ShapeOpts
Section titled “ShapeOpts”Options for addBox, addEllipse, and addDiamond:
| Option | Type | Default | Description |
|---|---|---|---|
row | number | — | Grid row position |
col | number | — | Grid column position |
color | ColorPreset | — | Semantic color preset |
width | number | — | Element width |
height | number | — | Element height |
x | number | — | Absolute x position (bypasses grid) |
y | number | — | Absolute y position (bypasses grid) |
strokeColor | string | — | Hex stroke color override |
backgroundColor | string | — | Hex background color override |
fillStyle | "solid" | "hachure" | "cross-hatch" | "zigzag" | "solid" | Fill style |
strokeWidth | number | 2 | Stroke width |
strokeStyle | "solid" | "dashed" | "dotted" | "solid" | Stroke style |
roughness | number | — | 0=architect, 1=artist, 2=cartoonist |
opacity | number | — | 0-100 |
roundness | { type: number } | null | — | Corner roundness |
fontSize | number | 16 | Label font size |
fontFamily | 1 | 2 | 3 | 1 | Virgil / Helvetica / Cascadia |
textAlign | "left" | "center" | "right" | — | Text alignment |
verticalAlign | "top" | "middle" | — | Vertical alignment |
link | string | null | — | Hyperlink URL |
customData | Record<string, unknown> | null | — | Arbitrary metadata |
icon | string | — | Icon preset ("database", "cloud", "lock", "server", "docker", "lambda", "api", "queue", "cache", "user", "k8s") or raw emoji |
ConnectOpts
Section titled “ConnectOpts”Options for connect():
| Option | Type | Default | Description |
|---|---|---|---|
style | "solid" | "dashed" | "dotted" | "solid" | Stroke style |
strokeColor | string | — | Hex stroke color |
strokeWidth | number | — | Stroke width |
roughness | number | — | Roughness level |
opacity | number | — | 0-100 |
startArrowhead | Arrowhead | null | Start arrowhead type |
endArrowhead | Arrowhead | "arrow" | End arrowhead type |
elbowed | boolean | — | Orthogonal routing (Graphviz handles routing by default) |
labelFontSize | number | — | Label font size |
labelPosition | "start" | "middle" | "end" | "middle" | Where to place the edge label along the arrow |
customData | Record<string, unknown> | null | — | Arbitrary metadata |
Arrowhead
Section titled “Arrowhead”null | "arrow" | "bar" | "dot" | "triangle" | "diamond" | "diamond_outline"
ColorPreset
Section titled “ColorPreset”See Color Presets for the full list with hex values.