This skill should be used when generating Excalidraw JSON files, creating visual diagrams in Excalidraw format, or needing to understand Excalidraw element structure...
Generate valid Excalidraw JSON files that can be opened in excalidraw.com or VS Code Excalidraw extension.
Every Excalidraw file follows this structure:
{
"type": "excalidraw",
"version": 2,
"source": "sketch-note-plugin",
"elements": [],
"appState": {
"viewBackgroundColor": "#ffffff",
"gridSize": null,
"theme": "light"
},
"files": {}
}
{
"type": "rectangle",
"id": "rect-1705312222-a7f3",
"x": 100,
"y": 100,
"width": 200,
"height": 100,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#a5d8ff",
"fillStyle": "hachure",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 2,
"opacity": 100,
"groupIds": [],
"frameId": null,
"roundness": { "type": 3 },
"seed": 12345,
"version": 1,
"versionNonce": 67890,
"isDeleted": false,
"boundElements": null,
"updated": 1705312222000,
"link": null,
"locked": false
}
{
"type": "ellipse",
"id": "ellipse-1705312222-b8c4",
"x": 100,
"y": 100,
"width": 150,
"height": 100,
"strokeColor": "#1e1e1e",
"backgroundColor": "#b2f2bb",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 2
}
{
"type": "diamond",
"id": "diamond-1705312222-c9d5",
"x": 100,
"y": 100,
"width": 120,
"height": 120,
"strokeColor": "#1e1e1e",
"backgroundColor": "#ffec99",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 2
}
{
"type": "text",
"id": "text-1705312222-d0e6",
"x": 100,
"y": 100,
"width": 150,
"height": 25,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 1,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"text": "Label text here",
"fontSize": 20,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"containerId": null,
"originalText": "Label text here",
"lineHeight": 1.25
}
Font families:
1 = Normal (sans-serif)2 = Code (monospace)3 = Virgil (handwriting){
"type": "arrow",
"id": "arrow-1705312222-e1f7",
"x": 300,
"y": 150,
"width": 100,
"height": 50,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "hachure",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 2,
"opacity": 100,
"points": [
[0, 0],
[100, 50]
],
"lastCommittedPoint": null,
"startBinding": {
"elementId": "rect-source",
"focus": 0,
"gap": 5
},
"endBinding": {
"elementId": "rect-target",
"focus": 0,
"gap": 5
},
"startArrowhead": null,
"endArrowhead": "arrow"
}
Arrowhead types:
null = No arrowhead"arrow" = Standard arrow"bar" = Bar/line"dot" = Circle"triangle" = Filled triangle{
"type": "line",
"id": "line-1705312222-f2g8",
"x": 100,
"y": 100,
"width": 200,
"height": 0,
"points": [
[0, 0],
[200, 0]
],
"strokeColor": "#1e1e1e",
"strokeWidth": 2,
"roughness": 2
}
| Value | Description |
|---|---|
"hachure" |
Hand-drawn diagonal lines (default, sketch-like) |
"cross-hatch" |
Crossed diagonal lines |
"solid" |
Solid fill |
"zigzag" |
Zigzag pattern |
"zigzag-line" |
Zigzag line pattern |
| Value | Description |
|---|---|
"solid" |
Continuous line |
"dashed" |
Dashed line |
"dotted" |
Dotted line |
| Value | Appearance |
|---|---|
0 |
Clean, precise lines |
1 |
Slightly rough, sketchy |
2 |
Very rough, hand-drawn look |
"roundness": { "type": 3 }
| Type | Description |
|---|---|
1 |
Sharp corners |
2 |
Round corners (legacy) |
3 |
Adaptive round corners |
| Name | Hex | Use Case |
|---|---|---|
| Light Blue | #a5d8ff |
Primary elements |
| Light Green | #b2f2bb |
Success, secondary |
| Light Yellow | #ffec99 |
Warnings, highlights |
| Light Red | #ffc9c9 |
Errors, alerts |
| Light Gray | #e9ecef |
Neutral, disabled |
| Light Purple | #d0bfff |
Special, accent |
| Light Orange | #ffd8a8 |
Attention |
| Name | Hex |
|---|---|
| White | #ffffff |
| Cream | #faf8f5 |
| Light Gray | #f5f5f5 |
| Light Blue | #f0f8ff |
| Light Yellow | #fffef0 |
| Name | Hex |
|---|---|
| Default | #1e1e1e |
| Blue | #1971c2 |
| Green | #2f9e44 |
| Red | #e03131 |
| Orange | #f08c00 |
Connect arrows to shapes:
{
"startBinding": {
"elementId": "rect-1",
"focus": 0,
"gap": 5
},
"endBinding": {
"elementId": "rect-2",
"focus": 0,
"gap": 5
}
}
Focus: -1 to 1, controls where arrow connects on element edge Gap: Pixels between arrow endpoint and element edge
When using bindings, add boundElements to the connected shapes:
{
"type": "rectangle",
"id": "rect-1",
"boundElements": [
{ "id": "arrow-1", "type": "arrow" }
]
}
Group elements together:
{
"type": "rectangle",
"id": "rect-1",
"groupIds": ["group-1"]
}
All elements with the same groupId move together.
Container for organizing elements:
{
"type": "frame",
"id": "frame-1",
"x": 50,
"y": 50,
"width": 400,
"height": 300,
"name": "Module A"
}
Elements inside set frameId:
{
"type": "rectangle",
"frameId": "frame-1"
}
Generate unique IDs with this pattern:
{type}-{timestamp}-{random4hex}
Examples:
rect-1705312222-a7f3arrow-1705312222-b8c4text-1705312222-c9d5For consistent roughness rendering, use deterministic seeds:
{
"seed": 12345,
"versionNonce": 67890
}
Generate seeds using timestamp or hash of element ID.
{
"type": "excalidraw",
"version": 2,
"source": "sketch-note-plugin",
"elements": [
{
"type": "rectangle",
"id": "rect-1",
"x": 100,
"y": 100,
"width": 150,
"height": 80,
"strokeColor": "#1e1e1e",
"backgroundColor": "#a5d8ff",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 2,
"boundElements": [
{ "id": "arrow-1", "type": "arrow" }
]
},
{
"type": "text",
"id": "text-1",
"x": 125,
"y": 130,
"width": 100,
"height": 25,
"text": "Start",
"fontSize": 20,
"fontFamily": 1,
"strokeColor": "#1e1e1e",
"containerId": "rect-1"
},
{
"type": "rectangle",
"id": "rect-2",
"x": 400,
"y": 100,
"width": 150,
"height": 80,
"strokeColor": "#1e1e1e",
"backgroundColor": "#b2f2bb",
"fillStyle": "hachure",
"strokeWidth": 2,
"roughness": 2,
"boundElements": [
{ "id": "arrow-1", "type": "arrow" }
]
},
{
"type": "arrow",
"id": "arrow-1",
"x": 250,
"y": 140,
"width": 150,
"height": 0,
"points": [[0, 0], [150, 0]],
"strokeColor": "#1e1e1e",
"strokeWidth": 2,
"roughness": 2,
"startBinding": {
"elementId": "rect-1",
"focus": 0,
"gap": 5
},
"endBinding": {
"elementId": "rect-2",
"focus": 0,
"gap": 5
},
"endArrowhead": "arrow"
}
],
"appState": {
"viewBackgroundColor": "#ffffff",
"gridSize": null
},
"files": {}
}
Before saving Excalidraw JSON:
id valuesboundElements arrays are synchronized with arrow bindingscontainerId references valid container elementtype field is set to "excalidraw"version is set to 2