Files
AGENTS/skills/excalidraw/references/json-format.md
m3tm3re 63cd7fe102 Rename directories to plural form: skill/ → skills/, agent/ → agents/, command/ → commands/
- Rename skill/ to skills/ for consistency with naming conventions
- Rename agent/ to agents/ and command/ to commands/
- Update AGENTS.md with all directory references
- Update scripts/test-skill.sh paths
- Update prompts/athena.txt documentation

This aligns with best practices of using plural directory names and updates
all documentation to reflect the new structure.
2026-01-26 20:42:05 +01:00

4.8 KiB

Excalidraw JSON Format Reference

Complete reference for Excalidraw JSON structure and element types.


File Structure

{
  "type": "excalidraw",
  "version": 2,
  "source": "claude-code-excalidraw-skill",
  "elements": [],
  "appState": {
    "gridSize": 20,
    "viewBackgroundColor": "#ffffff"
  },
  "files": {}
}

Element Types

Type Use For Arrow Reliability
rectangle Services, components, databases, containers, orchestrators, decision points Excellent
ellipse Users, external systems, start/end points Good
text Labels inside shapes, titles, annotations N/A
arrow Data flow, connections, dependencies N/A
line Grouping boundaries, separators N/A

BANNED: Diamond Shapes

NEVER use type: "diamond" in generated diagrams.

Diamond arrow connections are fundamentally broken in raw Excalidraw JSON:

  • Excalidraw applies roundness to diamond vertices during rendering
  • Visual edges appear offset from mathematical edge points
  • No offset formula reliably compensates
  • Arrows appear disconnected/floating

Use styled rectangles instead for visual distinction:

Semantic Meaning Rectangle Style
Orchestrator/Hub Coral (#ffa8a8/#c92a2a) + strokeWidth: 3
Decision Point Orange (#ffd8a8/#e8590c) + dashed stroke
Central Router Larger size + bold color

Required Element Properties

Every element MUST have these properties:

{
  "id": "unique-id-string",
  "type": "rectangle",
  "x": 100,
  "y": 100,
  "width": 200,
  "height": 80,
  "angle": 0,
  "strokeColor": "#1971c2",
  "backgroundColor": "#a5d8ff",
  "fillStyle": "solid",
  "strokeWidth": 2,
  "strokeStyle": "solid",
  "roughness": 1,
  "opacity": 100,
  "groupIds": [],
  "frameId": null,
  "roundness": { "type": 3 },
  "seed": 1,
  "version": 1,
  "versionNonce": 1,
  "isDeleted": false,
  "boundElements": null,
  "updated": 1,
  "link": null,
  "locked": false
}

Text Inside Shapes (Labels)

Every labeled shape requires TWO elements:

Shape with boundElements

{
  "id": "{component-id}",
  "type": "rectangle",
  "x": 500,
  "y": 200,
  "width": 200,
  "height": 90,
  "strokeColor": "#1971c2",
  "backgroundColor": "#a5d8ff",
  "boundElements": [{ "type": "text", "id": "{component-id}-text" }],
  // ... other required properties
}

Text with containerId

{
  "id": "{component-id}-text",
  "type": "text",
  "x": 505,                          // shape.x + 5
  "y": 220,                          // shape.y + (shape.height - text.height) / 2
  "width": 190,                      // shape.width - 10
  "height": 50,
  "text": "{Component Name}\n{Subtitle}",
  "fontSize": 16,
  "fontFamily": 1,
  "textAlign": "center",
  "verticalAlign": "middle",
  "containerId": "{component-id}",
  "originalText": "{Component Name}\n{Subtitle}",
  "lineHeight": 1.25,
  // ... other required properties
}

DO NOT Use the label Property

The label property is for the JavaScript API, NOT raw JSON files:

// WRONG - will show empty boxes
{ "type": "rectangle", "label": { "text": "My Label" } }

// CORRECT - requires TWO elements
// 1. Shape with boundElements reference
// 2. Separate text element with containerId

Text Positioning

  • Text x = shape x + 5
  • Text y = shape y + (shape.height - text.height) / 2
  • Text width = shape width - 10
  • Use \n for multi-line labels
  • Always use textAlign: "center" and verticalAlign: "middle"

ID Naming Convention

Always use pattern: {shape-id}-text for text element IDs.


Dynamic ID Generation

IDs and labels are generated from codebase analysis:

Discovered Component Generated ID Generated Label
Express API server express-api "API Server\nExpress.js"
PostgreSQL database postgres-db "PostgreSQL\nDatabase"
Redis cache redis-cache "Redis\nCache Layer"
S3 bucket for uploads s3-uploads "S3 Bucket\nuploads/"
Lambda function lambda-processor "Lambda\nProcessor"
React frontend react-frontend "React App\nFrontend"

Grouping with Dashed Rectangles

For logical groupings (namespaces, VPCs, pipelines):

{
  "id": "group-ai-pipeline",
  "type": "rectangle",
  "x": 100,
  "y": 500,
  "width": 1000,
  "height": 280,
  "strokeColor": "#9c36b5",
  "backgroundColor": "transparent",
  "strokeStyle": "dashed",
  "roughness": 0,
  "roundness": null,
  "boundElements": null
}

Group labels are standalone text (no containerId) at top-left:

{
  "id": "group-ai-pipeline-label",
  "type": "text",
  "x": 120,
  "y": 510,
  "text": "AI Processing Pipeline (Cloud Run)",
  "textAlign": "left",
  "verticalAlign": "top",
  "containerId": null
}