excalidraw
Create hand-drawn style diagrams using Excalidraw JSON format. Generate .excalidraw files for architecture diagrams, flowcharts, sequence diagrams, concept maps, and more. Files can be opened at excal
Create hand-drawn style diagrams using Excalidraw JSON format. Generate .excalidraw files for architecture diagrams, flowcharts, sequence diagrams, concept maps, and more. Files can be opened at excal
Real data. Real impact.
Emerging
Developers
Per week
Excellent
Skills give you superpowers. Install in 30 seconds.
Create diagrams by writing standard Excalidraw element JSON and saving as
.excalidraw files. These files can be drag-and-dropped onto excalidraw.com for viewing and editing. No accounts, no API keys, no rendering libraries -- just JSON.
write_file to create a .excalidraw filescripts/upload.py via terminalWrap your elements array in the standard
.excalidraw envelope and save with write_file:
{ "type": "excalidraw", "version": 2, "source": "hermes-agent", "elements": [ ...your elements array here... ], "appState": { "viewBackgroundColor": "#ffffff" } }
Save to any path, e.g.
~/diagrams/my_diagram.excalidraw.
Run the upload script (located in this skill's
scripts/ directory) via terminal:
python skills/diagramming/excalidraw/scripts/upload.py ~/diagrams/my_diagram.excalidraw
This uploads to excalidraw.com (no account needed) and prints a shareable URL. Requires the
cryptography pip package (pip install cryptography).
type, id (unique string), x, y, width, height
strokeColor: "#1e1e1e"backgroundColor: "transparent"fillStyle: "solid"strokeWidth: 2roughness: 1 (hand-drawn look)opacity: 100Canvas background is white.
Rectangle:
{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 100 }
roundness: { "type": 3 } for rounded cornersbackgroundColor: "#a5d8ff", fillStyle: "solid" for filledEllipse:
{ "type": "ellipse", "id": "e1", "x": 100, "y": 100, "width": 150, "height": 150 }
Diamond:
{ "type": "diamond", "id": "d1", "x": 100, "y": 100, "width": 150, "height": 150 }
Labeled shape (container binding) -- create a text element bound to the shape:
WARNING: Do NOT use
on shapes. This is NOT a valid Excalidraw property and will be silently ignored, producing blank shapes. You MUST use the container binding approach below."label": { "text": "..." }
The shape needs
boundElements listing the text, and the text needs containerId pointing back:
{ "type": "rectangle", "id": "r1", "x": 100, "y": 100, "width": 200, "height": 80, "roundness": { "type": 3 }, "backgroundColor": "#a5d8ff", "fillStyle": "solid", "boundElements": [{ "id": "t_r1", "type": "text" }] }, { "type": "text", "id": "t_r1", "x": 105, "y": 110, "width": 190, "height": 25, "text": "Hello", "fontSize": 20, "fontFamily": 1, "strokeColor": "#1e1e1e", "textAlign": "center", "verticalAlign": "middle", "containerId": "r1", "originalText": "Hello", "autoResize": true }
containerId is setx/y/width/height are approximate -- Excalidraw recalculates them on loadoriginalText should match textfontFamily: 1 (Virgil/hand-drawn font)Labeled arrow -- same container binding approach:
{ "type": "arrow", "id": "a1", "x": 300, "y": 150, "width": 200, "height": 0, "points": [[0,0],[200,0]], "endArrowhead": "arrow", "boundElements": [{ "id": "t_a1", "type": "text" }] }, { "type": "text", "id": "t_a1", "x": 370, "y": 130, "width": 60, "height": 20, "text": "connects", "fontSize": 16, "fontFamily": 1, "strokeColor": "#1e1e1e", "textAlign": "center", "verticalAlign": "middle", "containerId": "a1", "originalText": "connects", "autoResize": true }
Standalone text (titles and annotations only -- no container):
{ "type": "text", "id": "t1", "x": 150, "y": 138, "text": "Hello", "fontSize": 20, "fontFamily": 1, "strokeColor": "#1e1e1e", "originalText": "Hello", "autoResize": true }
x is the LEFT edge. To center at position cx: x = cx - (text.length * fontSize * 0.5) / 2textAlign or width for positioningArrow:
{ "type": "arrow", "id": "a1", "x": 300, "y": 150, "width": 200, "height": 0, "points": [[0,0],[200,0]], "endArrowhead": "arrow" }
points: [dx, dy] offsets from element x, yendArrowhead: null | "arrow" | "bar" | "dot" | "triangle"strokeStyle: "solid" (default) | "dashed" | "dotted"{ "type": "arrow", "id": "a1", "x": 300, "y": 150, "width": 150, "height": 0, "points": [[0,0],[150,0]], "endArrowhead": "arrow", "startBinding": { "elementId": "r1", "fixedPoint": [1, 0.5] }, "endBinding": { "elementId": "r2", "fixedPoint": [0, 0.5] } }
fixedPoint coordinates: top=[0.5,0], bottom=[0.5,1], left=[0,0.5], right=[1,0.5]
Font sizes:
fontSize: 16 for body text, labels, descriptionsfontSize: 20 for titles and headingsfontSize: 14 for secondary annotations only (sparingly)fontSize below 14Element sizes:
See
references/colors.md for full color tables. Quick reference:
| Use | Fill Color | Hex |
|---|---|---|
| Primary / Input | Light Blue | |
| Success / Output | Light Green | |
| Warning / External | Light Orange | |
| Processing / Special | Light Purple | |
| Error / Critical | Light Red | |
| Notes / Decisions | Light Yellow | |
| Storage / Data | Light Teal | |
#757575references/dark-mode.mdreferences/examples.mdMIT
mkdir -p ~/.hermes/skills/creative/excalidraw && curl -o ~/.hermes/skills/creative/excalidraw/SKILL.md https://raw.githubusercontent.com/NousResearch/hermes-agent/main/skills/creative/excalidraw/SKILL.md1,500+ AI skills, agents & workflows. Install in 30 seconds. Part of the Torly.ai family.
© 2026 Torly.ai. All rights reserved.