Skip to main content
For comprehensive or technical diagrams, you must build the JSON one section at a time. This is a hard constraint—attempting to generate the entire file in a single pass will fail or produce poor quality results.

Why Section-by-Section?

There are three reasons this approach is mandatory:
  1. Token limits: Claude has a ~32,000 token output limit per response. A comprehensive diagram easily exceeds that in one shot.
  2. Quality: Generating everything at once leads to rushed decisions and inconsistent spacing.
  3. Maintainability: Section-by-section JSON with descriptive IDs is far easier to debug and modify.
What NOT to do:
  • Don’t generate the entire diagram in one response
  • Don’t use a coding agent to generate the JSON (lacks context about skill rules)
  • Don’t write a Python generator script (adds debugging complexity)

The Three-Phase Workflow

1
Phase 1: Build Each Section
2

1. Create the base file

Start with the JSON wrapper and the first section of elements:
{
  "type": "excalidraw",
  "version": 2,
  "source": "https://excalidraw.com",
  "elements": [
    // Section 1 elements go here
  ],
  "appState": {
    "viewBackgroundColor": "#ffffff",
    "gridSize": 20
  },
  "files": {}
}
The first section typically contains the entry point or trigger.
3

2. Add one section per edit

Each section gets its own dedicated pass. Take your time with it. Think carefully about:
  • Layout and spacing within the section
  • How this section connects to what’s already there
  • Visual balance relative to other sections
Add new sections by editing the elements array to append the new section’s elements.
4

3. Use descriptive string IDs

Use human-readable IDs like:
  • "trigger_rect"
  • "arrow_fan_left"
  • "code_snippet_api_request"
  • "timeline_dot_1"
This makes cross-section references readable and debugging much easier.
{
  "id": "trigger_rect",
  "type": "rectangle",
  // ...
}
5

4. Namespace seeds by section

To avoid seed collisions:
  • Section 1 uses 100xxx (100001, 100002, etc.)
  • Section 2 uses 200xxx (200001, 200002, etc.)
  • Section 3 uses 300xxx, and so on
Example:
// Section 1
{"id": "start_ellipse", "seed": 100001}

// Section 2  
{"id": "process_rect", "seed": 200001}
6

5. Update cross-section bindings

When a new section’s element needs to bind to an element from a previous section (e.g., an arrow connecting sections), edit both elements:
  1. The arrow’s startBinding or endBinding references the other element’s ID
  2. The other element’s boundElements array includes a reference to the arrow
Example: Arrow in Section 2 connecting to a rectangle in Section 1:
// Section 1 rectangle (updated)
{
  "id": "section1_rect",
  "type": "rectangle",
  // ...
  "boundElements": [
    {"id": "arrow_section2_to_section1", "type": "arrow"}
  ]
}

// Section 2 arrow
{
  "id": "arrow_section2_to_section1",
  "type": "arrow",
  // ...
  "endBinding": {
    "elementId": "section1_rect",
    "focus": 0,
    "gap": 10
  }
}
Update the previous section’s element at the same time you add the new arrow.
7
Phase 2: Review the Whole
8
After all sections are in place, read through the complete JSON and check:
9
Verify that arrows connecting different sections have:
  • Valid startBinding/endBinding with correct elementId
  • Corresponding entries in the bound elements’ boundElements arrays
Check that:
  • No sections are cramped while others have too much whitespace
  • Similar elements have consistent spacing
  • Visual weight is distributed evenly
Search for any orphaned references:
  • elementId in bindings points to real elements
  • All boundElements entries reference arrows that exist
10
Fix any alignment or binding issues before proceeding to rendering.
11
Phase 3: Render & Validate
12
Now run the render-view-fix loop. This is where you’ll catch visual issues that aren’t obvious from JSON:
13
  • Overlaps
  • Text clipping
  • Imbalanced composition
  • Arrows crossing through elements
  • 14
    See the Render & Validate guide for the complete process.

    Planning Section Boundaries

    Plan your sections around natural visual groupings from your diagram plan. A typical large diagram might split into:
    1
    Section 1: Entry Point / Trigger
    2
    The starting point of the flow. Usually contains:
    3
  • Start shape (ellipse)
  • Initial trigger or input
  • First action or decision
  • 4
    Section 2: First Decision or Routing
    5
    Where the flow branches or makes its first major choice:
    6
  • Decision diamond
  • Multiple paths (fan-out pattern)
  • Routing logic
  • 7
    Section 3: Main Content (Hero Section)
    8
    This is often the largest single section containing:
    9
  • The core transformation or process
  • Evidence artifacts (code snippets, data examples)
  • Multiple sub-components
  • 10
    Sections 4-N: Remaining Phases
    11
    Subsequent sections for:
    12
  • Additional processing steps
  • Outputs and results
  • Error handling or edge cases
  • Summary or conclusion
  • Each section should be independently understandable: its elements, internal arrows, and any cross-references to adjacent sections should form a coherent unit.

    Example: Section-by-Section Workflow

    Here’s a concrete example of building a 4-section diagram:
    # Create file with Section 1 (entry point)
    touch diagram.excalidraw
    
    # Add JSON wrapper + Section 1 elements:
    # - Start ellipse (id: "start_ellipse", seed: 100001)
    # - Trigger text (id: "trigger_text", seed: 100002)
    # - Arrow to next section placeholder
    

    Multi-Zoom Architecture

    Comprehensive diagrams operate at multiple zoom levels simultaneously. For large diagrams, ensure you include all three levels:

    Level 1: Summary Flow

    A simplified overview showing the full pipeline at a glance. Often placed at the top or bottom. Example: Input → Processing → Output or Client → Server → Database

    Level 2: Section Boundaries

    Labeled regions that group related components. These create visual “rooms” that help viewers understand what belongs together. Example: Grouping by responsibility (Backend / Frontend), by phase (Setup / Execution / Cleanup), or by team (User / System / External)

    Level 3: Detail Inside Sections

    Evidence artifacts, code snippets, and concrete examples within each section. This is where the educational value lives. Example: Inside a “Backend” section, show the actual API response format, not just a box labeled “API Response”
    For comprehensive diagrams, aim to include all three levels. The summary gives context, the sections organize, and the details teach.

    Troubleshooting

    Check:
    1. Arrow’s endBinding.elementId matches the target element’s id
    2. Target element’s boundElements includes {"id": "arrow_id", "type": "arrow"}
    3. Both elements exist in the elements array
    After adding all sections, adjust:
    • Element sizes (width/height) to rebalance visual weight
    • Spacing between sections (200-400px recommended)
    • Font sizes for hierarchy consistency
    Use descriptive IDs! Search for the ID string in your JSON. If using random IDs like "x7k2m9", you’ll waste time hunting.

    Next Steps

    Render & Validate

    Learn the mandatory render-view-fix loop

    Element Templates

    Copy-paste templates for all element types

    Build docs developers (and LLMs) love