Skip to main content

Overview

The render pipeline converts .excalidraw JSON files into high-quality PNG images using a Python script that orchestrates Playwright, headless Chromium, and the Excalidraw library. Location: references/render_excalidraw.py

Quick Start

First-Time Setup

Basic Usage

This creates <filename>.png next to the source .excalidraw file.

Advanced Options

path
required
Path to the .excalidraw JSON file to render
path
Output PNG path (default: same name as input with .png extension)
int
default:"2"
Device scale factor for high-DPI rendering (2 = retina quality)
int
default:"1920"
Maximum viewport width in pixels

Architecture

Pipeline Stages

1. Validation

The script validates the Excalidraw JSON structure before attempting to render:
references/render_excalidraw.py
What it checks:
  • type field must be "excalidraw"
  • elements array must exist and be a valid array
  • At least one element must be present (no empty diagrams)

2. Bounding Box Calculation

The script computes the smallest rectangle that contains all diagram elements:
references/render_excalidraw.py
Special handling:
  • Skips deleted elements (isDeleted: true)
  • Handles arrows/lines by iterating through their points array
  • Adds 80px padding on all sides
  • Falls back to 800×600 if no elements found

3. Viewport Configuration

references/render_excalidraw.py
Sizing logic:
  • Calculates natural diagram dimensions from bounding box
  • Adds 80px padding on all sides
  • Caps width at max_width (default 1920px)
  • Ensures minimum height of 600px

4. Browser Rendering

The script uses Playwright to control a headless Chromium browser:
references/render_excalidraw.py
Render sequence:
  1. Launch headless Chromium with specified viewport and scale
  2. Load render_template.html from the same directory
  3. Wait for Excalidraw library to load from esm.sh CDN
  4. Call window.renderDiagram() with the JSON data
  5. Wait for render completion signal
  6. Screenshot the SVG element (not the whole page)

5. HTML Template

The template (render_template.html) provides a minimal HTML page that loads Excalidraw:
references/render_template.html
Key features:
  • Loads @excalidraw/excalidraw from esm.sh CDN (no build step)
  • Forces white background for consistent exports
  • Sets coordination flags (__moduleReady, __renderComplete) for Python to await
  • Returns structured success/error response

Dependencies

From pyproject.toml:
references/pyproject.toml
Runtime dependencies:
  • Python 3.11+
  • Playwright Python library
  • Chromium browser (installed via playwright install chromium)
  • Internet connection (to load Excalidraw library from esm.sh)

Error Handling

The script provides clear error messages for common failure modes:

Invalid JSON

Invalid Excalidraw Structure

Playwright Not Installed

Chromium Not Installed

Render Failure

Missing SVG Element

Output Format

On success, the script prints the output path to stdout:
This allows the render command to be used in scripts:

Performance Characteristics

  • Cold start: ~3-5 seconds (browser launch + library load)
  • Warm render: ~1-2 seconds (subsequent renders in same process)
  • Memory: ~150-300 MB per browser instance
  • Network: Downloads Excalidraw library (~500KB) on first page load

Troubleshooting

The template can’t load the Excalidraw library from esm.sh. Check your internet connection or firewall settings.
The bounding box calculation may not account for all elements. Try increasing the --width parameter or checking for elements with unusual coordinate values.
Increase the --scale parameter. Default is 2 (retina quality). Try --scale 3 for even sharper text.
The render uses Excalidraw’s exportToSvg function, which may render colors slightly differently than the interactive editor. This is expected behavior.

Integration with Workflow

The render pipeline is a mandatory step in the diagram creation workflow (see Quality Checklist):
See the Render & Validate section in SKILL.md for the complete validation loop.