
Excalidraw Generator
- 2 installs
- 134 repo stars
- Updated June 29, 2026
- kv0906/pm-kit
Generates complete, valid .excalidraw.json files for flowcharts, architecture, UML, and mind maps that open directly at excalidraw.com.
About
Creates ready-to-open Excalidraw JSON diagrams (flowcharts, architecture, UML, mind maps) in professional or hand-drawn style. A developer uses it only when they explicitly want a diagram built as an Excalidraw file.
- Outputs valid .excalidraw.json with a 20px grid layout system
- Professional and hand-drawn visual styles for multiple diagram types
Excalidraw Generator by the numbers
- 2 all-time installs (skills.sh)
- Ranked #1,294 of 1,879 Documentation skills by installs in the Skillselion catalog
- Data as of Aug 2, 2026 (Skillselion catalog sync)
npx skills add https://github.com/kv0906/pm-kit --skill excalidraw-generatorAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 2 |
|---|---|
| repo stars | ★ 134 |
| Last updated | June 29, 2026 |
| Repository | kv0906/pm-kit ↗ |
What it does
Generates complete, valid .excalidraw.json files for flowcharts, architecture, UML, and mind maps that open directly at excalidraw.com.
Files
Excalidraw Diagram Generator
Create complete, valid .excalidraw.json files that users can directly open at excalidraw.com.
Core Capabilities
Diagram types supported:
- Flowcharts - Process flows, decision trees, workflows
- Architecture Diagrams - System architectures, network topologies, component diagrams
- UML Diagrams - Class diagrams, sequence diagrams, use case diagrams
- Mind Maps - Hierarchical concept maps, brainstorming diagrams
Two visual styles:
- Professional Mode (default): Clean, polished diagrams for technical documentation
- Hand-drawn Mode: Sketch-style diagrams for brainstorming and informal use
---
Quick Reference
JSON Schema
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}Coordinate System
- Origin: Top-left corner (0, 0)
- X-axis: Increases rightward
- Y-axis: Increases downward
- Unit: Pixels
Grid-Based Layout System
Use a 20px grid for alignment:
GRID_UNIT = 20
COLUMN_WIDTH = 200 # Element + gap
ROW_HEIGHT = 150 # Element + gap
Position formula:
x = START_X + (column * COLUMN_WIDTH)
y = START_Y + (row * ROW_HEIGHT)
Recommended START_X = 50, START_Y = 100Standard Element Sizes
| Element | Width | Height | Use Case |
|---|---|---|---|
| Small box | 120 | 60 | Labels, simple steps |
| Standard box | 160 | 80 | Process steps |
| Large box | 200 | 100 | Detailed nodes |
| Wide box | 240 | 80 | Long text |
| Diamond | 100 | 100 | Decision points |
| Circle | 80 | 80 | Start/End nodes |
---
Text Calculations (CRITICAL)
Text Height Formula
textHeight = fontSize × lineHeight × numberOfLines
= fontSize × 1.25 × numberOfLines
Examples:
- 1 line, fontSize 20: 20 × 1.25 × 1 = 25px
- 3 lines, fontSize 14: 14 × 1.25 × 3 = 52.5px ≈ 53px
- 12 lines, fontSize 15: 15 × 1.25 × 12 = 225pxText Centering Formula
text_x = shape_x + (shape_width - text_width) / 2
text_y = shape_y + (shape_height - text_height) / 2Text Size Reference
| Font Size | Char Width | Line Height | Use |
|---|---|---|---|
| 11 | ~6px | 15px | Labels, annotations |
| 12 | ~7px | 16px | Secondary text |
| 14 | ~8px | 18px | Body text |
| 16 | ~9px | 20px | Primary text |
| 18 | ~10px | 24px | Headings |
| 20 | ~11px | 26px | Titles |
| 28 | ~16px | 35px | Icons/Emoji |
Estimate text_width: char_count × char_width
Centering Example
Shape: x=100, y=100, width=160, height=80
Text: "Process" (7 chars), fontSize=16
text_width = 7 × 9 = 63
text_height = 1 × 20 = 20
text_x = 100 + (160 - 63) / 2 = 148.5 ≈ 148
text_y = 100 + (80 - 20) / 2 = 130UML Class Diagram Container Height
containerHeight = headerHeight + attributesHeight + methodsHeight + padding
Where:
- headerHeight = classNameTextHeight + topPadding (typically 15px + 15px = 30px)
- attributesHeight = fontSize × 1.25 × numberOfAttributes + 10px
- methodsHeight = fontSize × 1.25 × numberOfMethods + 10px
Example (12 attributes, 10 methods, fontSize 15):
- Header: 20 + 15 = 35px
- Attributes: 15 × 1.25 × 12 + 10 = 235px
- Methods: 15 × 1.25 × 10 + 10 ≈ 198px
- Total: 35 + 10 + 235 + 10 + 198 = 488px (round to 500px)---
Arrow Positioning
Horizontal Arrow (Left to Right)
From shape at (x1, y1, w1, h1) to shape at (x2, y2, w2, h2):
arrow_x = x1 + w1 # Right edge of source
arrow_y = y1 + h1/2 # Vertical center
gap = x2 - (x1 + w1) # Space between shapes
points = [[0, 0], [gap, 0]]Vertical Arrow (Top to Bottom)
arrow_x = x1 + w1/2 # Horizontal center
arrow_y = y1 + h1 # Bottom edge of source
gap = y2 - (y1 + h1)
points = [[0, 0], [0, gap]]Feedback Loop (Return Arrow)
From bottom-right back to left:
Start: (800, 400)
points=[
[0, 0], # Start
[0, 80], # Down
[-400, 80], # Left
[-400, -150] # Up to target
]---
Z-Order (Element Array Order)
Elements render in array order. First = back, last = front.
Correct order: 1. Background shapes (containers, frames) 2. Connection lines/arrows 3. Foreground shapes (nodes, boxes) 4. Text labels 5. Icons/overlays
---
Visual Styles
Professional Mode (Default)
Use for: Architecture diagrams, UML, technical docs, formal presentations
{
"roughness": 0,
"fillStyle": "solid",
"strokeWidth": 2,
"fontFamily": 2
}Colors (light backgrounds for readability):
| Purpose | Background |
|---|---|
| Primary | #e7f5ff |
| Success | #ebfbee |
| Warning | #fff9db |
| Accent | #f3f0ff |
| Secondary | #fff4e6 |
Hand-drawn Mode
Use for: Brainstorming, sketches, informal sharing
{
"roughness": 1,
"fillStyle": "hachure",
"strokeWidth": 2,
"fontFamily": 1
}Colors (medium saturation):
| Purpose | Background |
|---|---|
| Primary | #a5d8ff |
| Success | #b2f2bb |
| Warning | #ffec99 |
| Error | #ffc9c9 |
| Accent | #d0bfff |
| Secondary | #ffd8a8 |
Stroke color: #1e1e1e (dark gray, softer than pure black)
---
Element Types
Common Properties (required for all)
{
"id": "unique-id",
"type": "rectangle",
"x": 100,
"y": 100,
"width": 160,
"height": 80,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}Type-Specific Properties
Rectangle: Add "roundness": {"type": 3} for rounded corners
Text:
{
"type": "text",
"text": "Content\nLine 2",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle"
}- fontFamily: 1=Virgil (hand), 2=Helvetica, 3=Cascadia (mono)
Arrow/Line:
{
"type": "arrow",
"points": [[0, 0], [100, 0]],
"startArrowhead": null,
"endArrowhead": "arrow"
}- Points are relative to element's x,y
- Arrowheads:
null,"arrow","bar","dot","triangle"
---
Workflow
Step 1: Identify Diagram Type
Match the request to a diagram type:
- Flowchart: Process flows, algorithms, decision trees, workflows
- Architecture: System designs, microservices, cloud infrastructure
- UML Class: Object-oriented design, class hierarchies, relationships
- Mind Map: Brainstorming, concept hierarchies, topic exploration
Step 2: Use Templates as Foundation
Templates in assets/:
flowchart-template.jsonarchitecture-template.jsonuml-class-template.jsonmindmap-template.json
Usage: 1. Read the appropriate template 2. Modify IDs, text, positions, colors 3. Add/remove elements as needed 4. Ensure all IDs are unique
Step 3: Generate Elements
Key element types:
rectangle- Boxes, containers, processesellipse- Start/end nodes, databasesdiamond- Decisions, conditional branchesarrow/line- Connections, flowstext- Labels, descriptions
Step 4: Calculate Layout
Use the grid system and text centering formulas above.
Layout strategies:
- Flowcharts: Top-to-bottom, centered alignment
- Architecture: Left-to-right for flow, grouped by layer
- UML Class: Use container height formula; prevent text overflow
- Mind Maps: Radial from center, balanced branches
Step 5: Style and Polish
1. Choose visual style (Professional or Hand-drawn) 2. Apply consistent colors from the palette 3. Ensure adequate spacing (80-100px between elements)
Step 6: Save to File
Always save directly as `.excalidraw.json` (no code blocks).
1. Write complete JSON to file 2. Name descriptively (e.g., user-login-flow.excalidraw.json) 3. Save to current directory unless specified otherwise
After saving, provide: 1. Confirmation with file path 2. Brief description of diagram structure 3. Instructions: "Open at excalidraw.com → Menu → Open"
---
Common Patterns
Pattern 1: Sequential Flow
For A → B → C processes: 1. Place elements vertically with 120px gaps 2. Use rectangles for processes, ellipses for start/end 3. Connect with arrows (endArrowhead: "arrow") 4. Center-align all elements
Pattern 2: Decision Tree
For conditional branches: 1. Use diamond for decision nodes 2. Branch arrows left/right or up/down 3. Add text labels on arrows ("Yes", "No") 4. Rejoin paths when appropriate
Pattern 3: Hierarchical Structure
For layered architectures: 1. Group elements by layer (horizontal rows) 2. Use different colors per layer 3. Vertical arrows show dependencies 4. Consistent element sizes within layers
Pattern 4: Radial Mind Map
For concept exploration: 1. Central node (ellipse) in middle 2. Lines radiate outward 3. Different colors per branch 4. Rectangles for sub-topics
---
Positioning Checklist
Before generating: 1. Define grid: START_X, START_Y, COLUMN_WIDTH, ROW_HEIGHT 2. List all elements with row/column positions 3. Calculate exact x,y using formulas 4. Calculate text positions using centering formula 5. Calculate arrow start points and relative endpoints 6. Order elements correctly for z-order 7. Assign unique IDs and incrementing seeds
---
Complete Node Example
[
{
"id": "node1-box",
"type": "rectangle",
"x": 100, "y": 100, "width": 160, "height": 80,
"strokeColor": "#1971c2",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": [{"id": "arrow1", "type": "arrow"}],
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "node1-text",
"type": "text",
"x": 130, "y": 130,
"width": 100, "height": 20,
"text": "Process Step",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 101,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}
]---
Tips for Quality Diagrams
1. Unique IDs: Generate random 8-16 character IDs for each element 2. Consistent spacing: Follow spacing guidelines strictly 3. Color harmony: Use the recommended color palette 4. Text sizing: Match text width to container width with padding 5. Arrow connections: Position arrow start/end points precisely 6. Version numbers: Use random integers for versionNonce and seed
Handling Complex Requests
For large or complex diagrams: 1. Start simple: Create core structure first 2. Iterate: Add details progressively 3. Group logically: Use visual grouping (colors, spacing) 4. Limit complexity: Suggest breaking into multiple diagrams if needed 5. Maintain readability: Ensure text doesn't overlap, adequate spacing
---
Resources
assets/
Templates for common diagram types:
flowchart-template.jsonarchitecture-template.jsonuml-class-template.jsonmindmap-template.json
references/
excalidraw-format.md- Complete JSON format specificationelements.md- Element types and propertiesprocessing-loop-template.md- Processing loop example
Excalidraw Elements Reference
Complete specification for all Excalidraw element types.
Table of Contents
1. Common Properties 2. Rectangle 3. Ellipse 4. Diamond 5. Text 6. Arrow 7. Line 8. Frame 9. Image
---
Common Properties
Every element requires these properties:
{
"id": "string", // Unique identifier
"type": "string", // Element type
"x": 0, // X position (top-left corner)
"y": 0, // Y position (top-left corner)
"width": 100, // Width in pixels
"height": 50, // Height in pixels
"strokeColor": "#1e1e1e", // Border/stroke color
"backgroundColor": "transparent", // Fill color or "transparent"
"fillStyle": "solid", // "solid" | "hachure" | "cross-hatch"
"strokeWidth": 1, // 1 (thin) | 2 (medium) | 4 (thick)
"roughness": 1, // 0 (architect) | 1 (artist) | 2 (cartoonist)
"opacity": 100, // 0-100
"angle": 0, // Rotation in radians
"seed": 1, // Random seed for hand-drawn effect
"version": 1, // Element version
"isDeleted": false,
"boundElements": null, // Array of bound elements or null
"link": null, // Hyperlink or null
"locked": false
}Property Details
strokeColor / backgroundColor
Hex color codes. Common options:
- Transparent:
"transparent" - Black:
"#1e1e1e" - White:
"#ffffff" - Colors: See color palette in SKILL.md
fillStyle
"solid": Solid fill"hachure": Diagonal lines (hand-drawn look)"cross-hatch": Cross-hatched lines
roughness
0: Clean, architect style1: Hand-drawn, artist style (default)2: Sketchy, cartoonist style
boundElements
Array of objects linking this element to others:
"boundElements": [
{"id": "arrow1", "type": "arrow"},
{"id": "text1", "type": "text"}
]---
Rectangle
{
"type": "rectangle",
"roundness": {"type": 3} // Optional: rounded corners
// ... common properties
}Roundness Options
nullor omitted: Sharp corners{"type": 3}: Rounded corners (proportional to size){"type": 2}: Less rounded
---
Ellipse
{
"type": "ellipse"
// ... common properties
}Circle: Set equal width and height.
---
Diamond
{
"type": "diamond"
// ... common properties
}Used for decision points in flowcharts.
---
Text
{
"type": "text",
"text": "Your text here\nSecond line",
"fontSize": 20, // Pixels
"fontFamily": 1, // 1=Virgil(hand), 2=Helvetica, 3=Cascadia(code)
"textAlign": "center", // "left" | "center" | "right"
"verticalAlign": "middle", // "top" | "middle"
"lineHeight": 1.25, // Optional
"baseline": 18 // Optional
// ... common properties
}Font Families
1: Virgil (hand-drawn style) - default2: Helvetica (clean sans-serif)3: Cascadia (monospace/code)
Multi-line Text
Use \n for line breaks in the text property.
---
Arrow
{
"type": "arrow",
"points": [[0, 0], [100, 0]], // Relative coordinates
"startBinding": null, // Link to start element
"endBinding": null, // Link to end element
"startArrowhead": null, // null | "arrow" | "bar" | "dot" | "triangle"
"endArrowhead": "arrow" // null | "arrow" | "bar" | "dot" | "triangle"
// ... common properties
}Points Array
- Relative to element's x,y position
- Minimum 2 points for straight line
- Add more points for curves/bends
// Straight horizontal arrow (50px)
"points": [[0, 0], [50, 0]]
// Right-angle arrow (down then right)
"points": [[0, 0], [0, 50], [100, 50]]
// Curved path with multiple segments
"points": [[0, 0], [25, -20], [50, 0], [75, 20], [100, 0]]Bindings
Connect arrows to shapes:
"startBinding": {
"elementId": "rectangle1",
"focus": 0, // -1 to 1, position on element edge
"gap": 5 // Space between arrow and element
}Arrowhead Types
null: No arrowhead"arrow": Standard arrow (>)"bar": Perpendicular line (|)"dot": Circle"triangle": Filled triangle
---
Line
{
"type": "line",
"points": [[0, 0], [100, 50]],
"startBinding": null,
"endBinding": null
// ... common properties
}Same as arrow but no arrowheads. Use for connectors without direction.
---
Frame
{
"type": "frame",
"name": "Frame Name" // Displayed label
// ... common properties
}Use frames to group elements visually.
---
Image
{
"type": "image",
"fileId": "abc123", // Reference to files object
"scale": [1, 1] // X and Y scale
// ... common properties
}Files Object
Images require an entry in the root files object:
"files": {
"abc123": {
"mimeType": "image/png",
"id": "abc123",
"dataURL": "data:image/png;base64,iVBORw0KGgo...",
"created": 1690295874454,
"lastRetrieved": 1690295874454
}
}---
Element Grouping
Group elements by adding them to the same group:
{
"id": "el1",
"groupIds": ["group1"],
// ...
},
{
"id": "el2",
"groupIds": ["group1"],
// ...
}Nested groups: "groupIds": ["innerGroup", "outerGroup"]
---
Z-Order
Elements render in array order. First element = back, last element = front.
To layer correctly: 1. Background shapes first 2. Connecting lines/arrows 3. Foreground shapes 4. Text on top
Excalidraw JSON Format Reference
File Structure
Excalidraw files use plaintext JSON with the following structure:
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [],
"appState": {},
"files": {}
}Core Attributes
- type: Must be
"excalidraw" - version: Schema version (use
2) - source:
"https://excalidraw.com" - elements: Array of canvas elements
- appState: Application configuration
- files: Image data for embedded elements (usually
{})
Element Types
Supported element types:
rectangle- Rectangular shapesellipse- Circles and ovalsdiamond- Diamond shapesarrow- Arrows with optional arrowheadsline- Straight linesfreedraw- Hand-drawn pathstext- Text labelsimage- Embedded imagesframe- Grouping frames
Common Element Properties
All elements share these properties:
{
"id": string, // Unique ID (use random string)
"type": string, // Element type
"x": number, // X position
"y": number, // Y position
"width": number, // Width
"height": number, // Height
"angle": number, // Rotation in radians (0 for no rotation)
"strokeColor": string, // Border color (hex, e.g., "#000000")
"backgroundColor": string, // Fill color (hex, e.g., "#ffffff" or "transparent")
"fillStyle": string, // "solid" | "hachure" | "cross-hatch"
"strokeWidth": number, // Border thickness (1, 2, 4)
"strokeStyle": string, // "solid" | "dashed" | "dotted"
"roughness": number, // 0 (smooth) to 2 (very rough)
"opacity": number, // 0-100
"groupIds": array, // Array of group IDs (usually [])
"frameId": null, // Parent frame ID (null if none)
"roundness": object|null, // Corner rounding config
"boundElements": array, // Connected elements (usually [])
"updated": number, // Timestamp
"link": null, // Hyperlink data
"locked": boolean, // Lock state (false)
"versionNonce": number, // Version number (use random int)
"isDeleted": boolean, // Deletion state (false)
"seed": number // Random seed for roughness
}Element-Specific Properties
Text Elements
{
"type": "text",
"text": string, // Text content
"fontSize": number, // Font size (16, 20, 28, 36)
"fontFamily": number, // 1 (Hand-drawn) | 2 (Normal) | 3 (Code)
"textAlign": string, // "left" | "center" | "right"
"verticalAlign": string, // "top" | "middle"
"baseline": number, // Baseline position
"containerId": null, // Container element ID
"originalText": string, // Original text (same as text)
"lineHeight": number // Line height multiplier (1.25)
}Arrow/Line Elements
{
"type": "arrow" | "line",
"points": array, // [[0,0], [x,y], ...] relative to element position
"lastCommittedPoint": array, // Last point
"startArrowhead": string|null, // "arrow" | "bar" | "dot" | null
"endArrowhead": string|null, // "arrow" | "bar" | "dot" | null
"startBinding": object|null, // Binding to other element
"endBinding": object|null // Binding to other element
}Rectangle/Ellipse/Diamond Elements
No additional properties beyond common properties. Ellipses/diamonds use width and height to define shape.
appState Structure
Minimal appState for valid files:
{
"gridSize": null,
"viewBackgroundColor": "#ffffff"
}Layout Guidelines
Automatic Layout Calculation
When generating diagrams, use these spacing guidelines:
- Minimum spacing between elements: 50-100px
- Standard element sizes:
- Small boxes: 100x60
- Medium boxes: 150x80
- Large boxes: 200x100
- Connector arrow offset: Start/end 10-20px from element edges
- Hierarchical spacing: Parent-child vertical gap of 120-150px
Text Height Calculation Formula
CRITICAL: Always calculate text height accurately:
textHeight = fontSize × lineHeight × numberOfLinesWhere lineHeight = 1.25 (Excalidraw default)
Examples:
- Single-line title (fontSize 20):
20 × 1.25 × 1 = 25px - 3-line methods list (fontSize 14):
14 × 1.25 × 3 = 52.5px(round to 53px) - 12-line properties list (fontSize 15):
15 × 1.25 × 12 = 225px
UML Class Diagram Layout
For UML class diagrams, calculate container heights dynamically:
Container height formula:
containerHeight = headerSection + attributesSection + methodsSection
Where:
- headerSection = classNameHeight + topPadding + dividerSpace
(typically: 20-25px + 15px + 10px = 45-50px)
- attributesSection = (fontSize × 1.25 × numberOfAttributes) + bottomPadding
(typically: computed height + 10px)
- methodsSection = (fontSize × 1.25 × numberOfMethods) + bottomPadding
(typically: computed height + 10px)Positioning guide:
classNameText.y = container.y + 15 (top padding)
divider1.y = classNameText.y + classNameText.height + 10
attributesText.y = divider1.y + 15
divider2.y = attributesText.y + attributesText.height + 10
methodsText.y = divider2.y + 15
container.height = methodsText.y + methodsText.height + 10 - container.yExample calculation (class with 12 attributes, 10 methods, fontSize 15):
- Class name (fontSize 20): 20 × 1.25 = 25px
- Attributes: 15 × 1.25 × 12 = 225px
- Methods: 15 × 1.25 × 10 = 187.5px ≈ 188px
- Container height: 45 + 235 + 198 = 478px (round to 480-500px)
ID Generation
Generate unique IDs using random strings (8-16 chars). Example: "abc123xyz789"
Coordinate System
- Origin (0, 0) is top-left of canvas
- All measurements in pixels
- Arrows use relative coordinates in
pointsarray from element's (x, y)
Example: Simple Flowchart Element
{
"id": "box1",
"type": "rectangle",
"x": 100,
"y": 100,
"width": 150,
"height": 80,
"angle": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "#a5d8ff",
"fillStyle": "solid",
"strokeWidth": 2,
"strokeStyle": "solid",
"roughness": 1,
"opacity": 100,
"groupIds": [],
"frameId": null,
"roundness": { "type": 3 },
"boundElements": [],
"updated": 1705276800000,
"link": null,
"locked": false,
"versionNonce": 123456789,
"isDeleted": false,
"seed": 987654321
}Color Palette Recommendations
Professional colors:
- Primary:
#4c6ef5(blue) - Success:
#51cf66(green) - Warning:
#ffd43b(yellow) - Error:
#ff6b6b(red) - Neutral:
#e9ecef(light gray) - Text:
#1e1e1e(dark gray)
Professional mode colors (light backgrounds for better readability):
- Blue:
#e7f5ff - Green:
#ebfbee - Yellow:
#fff9db - Red:
#ffe3e3 - Purple:
#f3f0ff - Orange:
#fff4e6
Hand-drawn mode colors (pastel/medium saturation):
- Blue:
#a5d8ff - Green:
#b2f2bb - Yellow:
#ffec99 - Red:
#ffc9c9 - Purple:
#d0bfff - Orange:
#ffd8a8
Processing Loop with Conditional Branching Template
Generic template for systems with: Input → Processor → Condition → Output/Action branches with feedback loop.
Use Cases
- AI agent tool-calling loops
- Order processing workflows
- Request handling systems
- API gateway routing
- Approval workflows
- Error handling pipelines
Template Variables
| Variable | Description | Examples |
|---|---|---|
{{INPUT_TEXT}} | Initial input/request | "Process order #123", "User query", "API request" |
{{INPUT_LABEL}} | Label for input arrow | "Request", "Query", "Order", "Message" |
{{PROCESSOR_TITLE}} | Main processor node title | "Order Processor", "Router", "Agent", "Handler" |
{{PROCESSOR_ICON}} | Emoji for processor | "🧠", "⚙️", "🔄", "📦" |
{{CAPABILITY_1}} | First capability/tool | "Validator", "Database", "API Call" |
{{CAPABILITY_1_COLOR}} | Color for capability 1 | "#868e96" (gray) |
{{CAPABILITY_2}} | Second capability/tool | "Notifier", "Logger", "Cache" |
{{CAPABILITY_2_COLOR}} | Color for capability 2 | "#1971c2" (blue) |
{{CONDITION_LABEL}} | Decision point label | "Route", "Validate", "Check", "Condition" |
{{OUTPUT_LABEL}} | Direct output path label | "Response", "Complete", "Success", "Done" |
{{OUTPUT_TEXT}} | Final output text | "Order confirmed", "Result: OK", "Done" |
{{ACTION_LABEL}} | Action path label | "Process", "Execute", "Handle", "Action" |
{{ACTION_ARGS}} | Action parameters | "id: 123\ntype: fulfillment" |
{{EXECUTOR_TITLE}} | Executor node title | "Executor", "Worker", "Handler", "Service" |
{{EXECUTOR_RESULT}} | Execution result | "success", "completed", "processed" |
{{FEEDBACK_LABEL}} | Feedback loop label | "Result", "Callback", "Response", "Update" |
Layout Coordinates
┌─────────────────────────────────────────────────────────────────────────────┐
│ Y=55-75: Direct output text │
│ │
│ Y=95-130: Node labels │
│ │
│ Y=155-235: Main flow (Processor → Condition → branches) │
│ │
│ Y=245-370: Executor area │
│ │
│ Y=380-510: Feedback loop path │
└─────────────────────────────────────────────────────────────────────────────┘
X positions:
- Input: 20-230
- Processor Node: 320-500
- Condition: 590-660
- Executor Node: 755-915Color Scheme
| Element | Stroke | Background | Purpose |
|---|---|---|---|
| Processor icon | #e03131 | #ffc9c9 | Main processing unit |
| Condition diamond | #1e1e1e | #1e1e1e | Decision point |
| Output arrow | #2f9e44 | - | Success/completion path |
| Action arrow | #e8590c | - | Processing/action path |
| Feedback arrow | #9c36b5 | - | Return/callback loop |
| Node boxes | #868e96 | transparent | Containers |
JSON Template
{
"type": "excalidraw",
"version": 2,
"source": "https://excalidraw.com",
"elements": [
{
"id": "input-text",
"type": "text",
"x": 20,
"y": 180,
"width": 200,
"height": 30,
"text": "{{INPUT_TEXT}}",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 100,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-input",
"type": "arrow",
"x": 230,
"y": 195,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 101,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-input",
"type": "text",
"x": 245,
"y": 165,
"width": 80,
"height": 25,
"text": "{{INPUT_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 102,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-box",
"type": "rectangle",
"x": 320,
"y": 120,
"width": 180,
"height": 150,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 200,
"version": 1,
"isDeleted": false,
"boundElements": null,
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "processor-label",
"type": "text",
"x": 320,
"y": 95,
"width": 180,
"height": 20,
"text": "{{PROCESSOR_TITLE}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 201,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-icon-bg",
"type": "ellipse",
"x": 365,
"y": 155,
"width": 90,
"height": 80,
"strokeColor": "#e03131",
"backgroundColor": "#ffc9c9",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 202,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "processor-icon",
"type": "text",
"x": 388,
"y": 182,
"width": 45,
"height": 25,
"text": "{{PROCESSOR_ICON}}",
"fontSize": 28,
"fontFamily": 1,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 203,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "capability-1",
"type": "text",
"x": 340,
"y": 245,
"width": 70,
"height": 20,
"text": "{{CAPABILITY_1}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_1_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 204,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "capability-2",
"type": "text",
"x": 420,
"y": 245,
"width": 80,
"height": 20,
"text": "{{CAPABILITY_2}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_2_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 205,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-to-condition",
"type": "arrow",
"x": 505,
"y": 195,
"width": 80,
"height": 0,
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 300,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [80, 0]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "condition-diamond",
"type": "diamond",
"x": 590,
"y": 160,
"width": 70,
"height": 70,
"strokeColor": "#1e1e1e",
"backgroundColor": "#1e1e1e",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 0,
"opacity": 100,
"angle": 0,
"seed": 400,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "condition-label",
"type": "text",
"x": 580,
"y": 130,
"width": 90,
"height": 25,
"text": "{{CONDITION_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 401,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-output",
"type": "arrow",
"x": 625,
"y": 155,
"width": 120,
"height": 80,
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 500,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [60, -80], [120, -80]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-output",
"type": "text",
"x": 660,
"y": 55,
"width": 60,
"height": 20,
"text": "{{OUTPUT_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#2f9e44",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 501,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "output-text",
"type": "text",
"x": 755,
"y": 60,
"width": 120,
"height": 30,
"text": "{{OUTPUT_TEXT}}",
"fontSize": 16,
"fontFamily": 1,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 502,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-action",
"type": "arrow",
"x": 625,
"y": 235,
"width": 120,
"height": 80,
"strokeColor": "#e8590c",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 600,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [60, 80], [120, 80]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-action",
"type": "text",
"x": 665,
"y": 300,
"width": 55,
"height": 20,
"text": "{{ACTION_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#e8590c",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 601,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "action-args",
"type": "text",
"x": 720,
"y": 330,
"width": 180,
"height": 35,
"text": "{{ACTION_ARGS}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 602,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-box",
"type": "rectangle",
"x": 755,
"y": 270,
"width": 160,
"height": 100,
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 700,
"version": 1,
"isDeleted": false,
"boundElements": null,
"roundness": {"type": 3},
"link": null,
"locked": false
},
{
"id": "executor-label",
"type": "text",
"x": 755,
"y": 245,
"width": 100,
"height": 20,
"text": "{{EXECUTOR_TITLE}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#1e1e1e",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 701,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-capability-1",
"type": "text",
"x": 775,
"y": 295,
"width": 70,
"height": 20,
"text": "{{CAPABILITY_1}}",
"fontSize": 12,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_1_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 702,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-capability-2",
"type": "text",
"x": 850,
"y": 295,
"width": 60,
"height": 20,
"text": "{{CAPABILITY_2}}",
"fontSize": 11,
"fontFamily": 2,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "{{CAPABILITY_2_COLOR}}",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 703,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "executor-description",
"type": "text",
"x": 755,
"y": 380,
"width": 220,
"height": 35,
"text": "Executes action and\nreturns result: {{EXECUTOR_RESULT}}",
"fontSize": 11,
"fontFamily": 3,
"textAlign": "left",
"verticalAlign": "middle",
"strokeColor": "#868e96",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 704,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
},
{
"id": "arrow-feedback",
"type": "arrow",
"x": 835,
"y": 375,
"width": 425,
"height": 130,
"strokeColor": "#9c36b5",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 2,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 800,
"version": 1,
"isDeleted": false,
"points": [[0, 0], [0, 130], [-425, 130], [-425, -100]],
"startArrowhead": null,
"endArrowhead": "arrow",
"link": null,
"locked": false
},
{
"id": "label-feedback",
"type": "text",
"x": 450,
"y": 490,
"width": 80,
"height": 20,
"text": "{{FEEDBACK_LABEL}}",
"fontSize": 12,
"fontFamily": 3,
"textAlign": "center",
"verticalAlign": "middle",
"strokeColor": "#9c36b5",
"backgroundColor": "transparent",
"fillStyle": "solid",
"strokeWidth": 1,
"roughness": 1,
"opacity": 100,
"angle": 0,
"seed": 801,
"version": 1,
"isDeleted": false,
"boundElements": null,
"link": null,
"locked": false
}
],
"appState": {
"gridSize": null,
"viewBackgroundColor": "#ffffff"
},
"files": {}
}Example Configurations
AI Agent Tool Loop
INPUT_TEXT: "What is magic_function(3)"
INPUT_LABEL: Human message
PROCESSOR_TITLE: Assistant Node (LLM w/ bound tools)
PROCESSOR_ICON: 🧠
CAPABILITY_1: Magic Fxn
CAPABILITY_2: Web Search
CONDITION_LABEL: Tools Condition
OUTPUT_LABEL: Response
OUTPUT_TEXT: The result is 5
ACTION_LABEL: Tool call
ACTION_ARGS: arguments: '{"input":3}'\nname: magic_function
EXECUTOR_TITLE: Tool Node
EXECUTOR_RESULT: '5'
FEEDBACK_LABEL: Tool messageOrder Processing System
INPUT_TEXT: "Order #12345"
INPUT_LABEL: New Order
PROCESSOR_TITLE: Order Processor
PROCESSOR_ICON: 📦
CAPABILITY_1: Inventory
CAPABILITY_2: Payment
CONDITION_LABEL: Validate
OUTPUT_LABEL: Complete
OUTPUT_TEXT: Order Confirmed
ACTION_LABEL: Fulfill
ACTION_ARGS: items: 3\nwarehouse: US-West
EXECUTOR_TITLE: Fulfillment Service
EXECUTOR_RESULT: shipped
FEEDBACK_LABEL: Status UpdateAPI Gateway Router
INPUT_TEXT: "GET /api/users/123"
INPUT_LABEL: HTTP Request
PROCESSOR_TITLE: API Gateway
PROCESSOR_ICON: 🔀
CAPABILITY_1: Auth
CAPABILITY_2: RateLimit
CONDITION_LABEL: Route
OUTPUT_LABEL: Cached
OUTPUT_TEXT: 200 OK (from cache)
ACTION_LABEL: Forward
ACTION_ARGS: service: user-svc\nmethod: GET
EXECUTOR_TITLE: Microservice
EXECUTOR_RESULT: user_data
FEEDBACK_LABEL: ResponseApproval Workflow
INPUT_TEXT: "Expense Report $5,000"
INPUT_LABEL: Submit
PROCESSOR_TITLE: Approval Engine
PROCESSOR_ICON: ✅
CAPABILITY_1: Policy
CAPABILITY_2: Budget
CONDITION_LABEL: Review
OUTPUT_LABEL: Auto-Approve
OUTPUT_TEXT: Approved
ACTION_LABEL: Escalate
ACTION_ARGS: approver: manager\namount: $5,000
EXECUTOR_TITLE: Manager Review
EXECUTOR_RESULT: approved
FEEDBACK_LABEL: DecisionVariations
Remove Feedback Loop
Delete: arrow-feedback, label-feedback
Add Third Capability
Duplicate capability elements, adjust positions:
- Y=265 for third row in both nodes
Multiple Executors
Duplicate executor section, shift Y by +150px each