Skip to main content
You cannot judge a diagram from JSON alone. After generating or editing the Excalidraw JSON, you must render it to PNG, view the image, and fix what you see—in a loop until it’s right. This is a core part of the workflow, not a final check.

Why This Is Mandatory

JSON shows you coordinates and IDs. The rendered image shows you:
  • Whether text is clipped or overflowing
  • Whether shapes overlap unintentionally
  • Whether arrows land on the right elements
  • Whether spacing is consistent
  • Whether the composition is balanced
  • Whether the visual hierarchy matches your intent
You will always find issues on first render. Budget for 2-4 iterations.

Setup (First Time Only)

If the render script hasn’t been set up yet:
1
Install dependencies
2
cd ~/.claude/skills/excalidraw-diagram/references
uv sync
3
Install Chromium for Playwright
4
uv run playwright install chromium
You only need to do this once.

The Render-View-Fix Loop

1
Step 1: Render to PNG
2
Run the render script with the path to your .excalidraw file:
3
cd ~/.claude/skills/excalidraw-diagram/references
uv run python render_excalidraw.py /path/to/your/diagram.excalidraw
4
This outputs a PNG file next to the .excalidraw file with the same name:
5
  • Input: diagram.excalidraw
  • Output: diagram.png
  • 6
    The script uses Playwright to load Excalidraw’s official renderer, ensuring pixel-perfect output matching what users will see.
    7
    Step 2: View the PNG
    8
    Use the Read tool to actually view the rendered image:
    9
    # In your conversation with the assistant:
    "Read the PNG at /path/to/your/diagram.png"
    
    10
    The assistant will display the image so you can visually inspect it.
    11
    Step 3: Audit Against Your Vision
    12
    Before looking for bugs, compare the rendered result to what you designed. Ask:
    13
    • Did you plan a fan-out pattern? Is it actually fanning out?
    • Did you plan a timeline? Does it read as a timeline?
    • Does each section use the pattern you intended?
    • Is there a clear visual path?
    • Do arrows guide the eye in the intended order?
    • Are there any dead ends or confusing jumps?
    • Are hero elements dominant?
    • Are supporting elements appropriately smaller?
    • Do font sizes create clear hierarchy?
    • Can you read the code snippets?
    • Are data examples properly formatted?
    • Do real event names/API calls stand out?
    14
    Step 4: Check for Visual Defects
    15
    Now look for specific visual problems:
    16
    Text Issues
    17
  • ✅ Text clipped by its container
  • ✅ Text overflowing beyond container edges
  • ✅ Text too small to read at the rendered size
  • ✅ Text overlapping other elements
  • 18
    Shape & Arrow Issues
    19
  • ✅ Shapes overlapping other shapes unintentionally
  • ✅ Arrows crossing through elements instead of routing around them
  • ✅ Arrows landing on the wrong element
  • ✅ Arrows pointing into empty space
  • ✅ Arrow bindings not visually connecting to intended elements
  • 20
    Layout Issues
    21
  • ✅ Labels floating ambiguously (not clearly anchored to what they describe)
  • ✅ Uneven spacing between elements that should be evenly spaced
  • ✅ Sections with too much whitespace next to cramped sections
  • ✅ Overall composition feels lopsided or unbalanced
  • 22
    Don’t skip the visual inspection step. Issues that are invisible in JSON become obvious in the rendered image.
    23
    Step 5: Fix
    24
    Edit the JSON to address everything you found. Common fixes:
    25
    Text Clipping
    Problem: Text is cut off inside a shape.Fix: Increase the shape’s width and/or height:
    {
      "id": "my_rect",
      "type": "rectangle",
      "width": 180,  // Increase from 120
      "height": 90,  // Increase from 60
      // ...
    }
    
    Element Overlap
    Problem: Shapes or text overlap unintentionally.Fix: Adjust x and y coordinates to add spacing:
    // Move element 2 to the right
    {
      "id": "element2",
      "x": 400,  // Increase from 300
      "y": 100
      // ...
    }
    
    Arrow Routing
    Problem: Arrow crosses through other elements.Fix: Add waypoints to the arrow’s points array to route around obstacles:
    {
      "id": "my_arrow",
      "type": "arrow",
      "points": [
        [0, 0],       // Start
        [100, 0],     // Waypoint 1 (go right)
        [100, 150],   // Waypoint 2 (go down)
        [200, 150]    // End
      ]
      // ...
    }
    
    Floating Labels
    Problem: Label isn’t clearly associated with its element.Fix: Move the label closer to the element it describes:
    {
      "id": "label_text",
      "x": 305,  // Adjust to be near the element
      "y": 105,  // Slight offset for clarity
      // ...
    }
    
    Unbalanced Composition
    Problem: Diagram feels lopsided.Fix: Resize elements to rebalance visual weight:
    // Make hero element larger
    {
      "id": "hero_rect",
      "width": 300,  // Increase from 180
      "height": 150  // Increase from 90
    },
    // Make supporting elements smaller
    {
      "id": "support_rect",
      "width": 120,  // Decrease from 180
      "height": 60   // Decrease from 90
    }
    
    26
    Step 6: Re-render & Re-view
    27
    Run the render script again:
    28
    cd ~/.claude/skills/excalidraw-diagram/references
    uv run python render_excalidraw.py /path/to/your/diagram.excalidraw
    
    29
    Then view the updated PNG to see if your fixes worked.
    30
    Step 7: Repeat
    31
    Keep cycling through steps 2-6 until the diagram passes both:
    32
  • Vision check (Step 3): matches your conceptual design
  • Defect check (Step 4): no visual issues
  • 33
    Typically takes 2-4 iterations.

    When to Stop

    The loop is done when: Don’t stop after one pass just because there are no critical bugs. If the composition could be better, improve it.

    Common Iteration Patterns

    Iteration 1: Fix Critical Issues

    First render usually reveals:
    • Text clipping (most common)
    • Major overlaps
    • Broken arrow bindings
    Fix these first.

    Iteration 2: Improve Spacing

    Second render shows:
    • Uneven gaps between elements
    • Sections that need more breathing room
    • Elements that could be closer together
    Adjust coordinates for better balance.

    Iteration 3: Polish

    Third render is for fine-tuning:
    • Font size adjustments
    • Minor alignment tweaks
    • Final arrow routing improvements

    Iteration 4: Final Check

    Fourth render confirms everything looks good. If new issues appear, continue iterating.

    Troubleshooting

    Install uv first:
    curl -LsSf https://astral.sh/uv/install.sh | sh
    
    Then retry the setup steps.
    Run the install command from the references directory:
    cd ~/.claude/skills/excalidraw-diagram/references
    uv run playwright install chromium
    
    This is normal! The rendered output often reveals issues invisible in JSON. That’s exactly why this step is mandatory.Follow the fix loop to address visual problems.
    Use the rendered PNG as a reference:
    1. Note which elements need to move
    2. Estimate the direction and distance (50px? 100px?)
    3. Find those elements in JSON by their id
    4. Adjust x/y coordinates
    5. Re-render to verify
    Trial and error is normal—that’s why you iterate.

    Advanced: Batch Rendering

    If you’re working on multiple diagrams, you can render them all at once:
    cd ~/.claude/skills/excalidraw-diagram/references
    for file in /path/to/diagrams/*.excalidraw; do
      uv run python render_excalidraw.py "$file"
    done
    
    This generates PNGs for all .excalidraw files in the directory.

    Next Steps

    Creating Diagrams

    Review the full end-to-end workflow

    Large Diagrams

    Section-by-section strategy for complex diagrams

    Quality Checklist

    Complete checklist for diagram quality

    Build docs developers (and LLMs) love