Excalidraw
Excalidraw is a virtual whiteboard tool that produces hand-drawn style diagrams. diagramkit renders .excalidraw JSON files using the official @excalidraw/excalidraw library in a headless Chromium page.
File Extensions
| Extension | Description |
|---|---|
.excalidraw | Standard Excalidraw file extension |
Installation
Excalidraw support is bundled with diagramkit:
npm add diagramkit
npx diagramkit warmupTIP
If you need raster output (png, jpeg, or webp), install sharp separately with npm add sharp.
JSON Format
Excalidraw files use a JSON format with three top-level keys:
{
"elements": [
{
"type": "rectangle",
"x": 100,
"y": 100,
"width": 200,
"height": 100,
"strokeColor": "#1e1e1e",
"backgroundColor": "#a5d8ff",
"fillStyle": "hachure",
"roughness": 1,
"opacity": 100
}
],
"appState": {
"viewBackgroundColor": "#ffffff"
},
"files": {}
}| Key | Description |
|---|---|
elements | Array of shapes, text, arrows, and other drawing elements |
appState | Application state including background color and theme |
files | Embedded binary files (images) referenced by elements |
The easiest way to create .excalidraw files is to draw in the Excalidraw editor and export as .excalidraw (JSON).
Example
Create system.excalidraw using the Excalidraw editor, then render:
diagramkit render system.excalidrawOutput:
.diagrams/
system-light.svg
system-dark.svgOr render from a directory:
diagramkit render . --type excalidrawDark Mode
Excalidraw handles dark mode natively through its exportToSvg API. When rendering:
- Light:
exportWithDarkMode: false, background#ffffff - Dark:
exportWithDarkMode: true, background#111111
Both variants are rendered in the same browser page (unlike Mermaid, which requires separate pages). The Excalidraw library handles color adjustments internally.
INFO
The WCAG contrast post-processing (--no-contrast flag) applies to Mermaid and Draw.io diagrams. Excalidraw handles dark mode natively via its own library.
Architecture
Excalidraw rendering uses a single browser page:
- The
@excalidraw/excalidraw,react, andreact-dompackages are bundled into an IIFE using rolldown - The IIFE exposes a
__renderExcalidraw(json, darkMode)function onglobalThis - The bundled code is loaded into a Playwright page once, then reused for all renders
- Each render call passes the JSON content and dark mode flag, receiving an SVG string back
The bundle is cached after the first build, so subsequent renders do not re-bundle.
Programmatic Usage
import { render } from 'diagramkit'
import { readFileSync } from 'fs'
const json = readFileSync('diagram.excalidraw', 'utf-8')
const result = await render(json, 'excalidraw', {
format: 'svg',
theme: 'both',
})
// result.light — Buffer containing light theme SVG
// result.dark — Buffer containing dark theme SVGTips for Excalidraw Diagrams
- Set
viewBackgroundColorto#ffffff-- dark mode is handled automatically during rendering - Use the default color palette -- custom colors may not contrast well in dark mode
- Keep elements spaced -- leave at least 20px padding between elements for readable output
- Export as
.excalidraw(JSON) -- do not export as SVG or PNG from the editor; diagramkit needs the raw JSON to render both theme variants