excalidraw-convert
Convert Excalidraw diagrams to editable PowerPoint vector objects or Lucid Package Format (.lucid).
Features
PowerPoint output
Each shape, arrow, and text box becomes a native PowerPoint object you can move, resize, recolour, and animate individually — not a flat image.
| Excalidraw element | PowerPoint output |
|---|---|
| Rectangle (with/without roundness) | Auto-shape (Rectangle / Rounded Rectangle) |
| Ellipse | Auto-shape (Oval) |
| Diamond | Auto-shape (Diamond) |
| Arrow (2-point) | Straight Connector with arrowheads |
| Line / Arrow (multi-point) | Freeform path |
| Freedraw | Freeform path (approximate) |
| Text (standalone) | Text Box |
| Text (bound to shape) | Text inside the parent shape |
| Image (PNG/JPEG/WEBP) | Embedded picture |
| Image (SVG) | PNG fallback (requires cairosvg) |
| Frame | Separate slide |
| No frames | Single slide (whole canvas) |
Lucid output
Produces a .lucid file (ZIP archive in Lucid Package Format) that can be opened directly in LucidChart or LucidSpark.
| Excalidraw element | Lucid output |
|---|---|
| Rectangle (with/without roundness) | rectangle shape |
| Ellipse | circle shape |
| Diamond | diamond shape |
| Arrow / Line (2-point) | elbow line connector |
| Arrow / Line (multi-point) | straight line with intermediate joints |
| Freedraw | flexiblePolygon (downsampled to ≤100 vertices) |
| Text (standalone) | text shape |
| Text (bound to shape) | Text property on the parent shape |
| Image | image shape with file embedded in the archive |
| Frame | Separate page |
| No frames | Single page (whole canvas) |
Styling carried over (both formats)
Fill colour, stroke colour, stroke width, dashed/dotted strokes, rounded corners, arrowhead types, opacity, background colour, multi-line text, font family, font size, and text alignment.
Installation
pip install excalidraw-convert
For SVG image support in PowerPoint output (optional):
pip install "excalidraw-convert[svg]"
To install from source:
pip install -e ".[dev]"
Usage
Command line
# Convert to PowerPoint
excalidraw-convert convert "https://excalidraw.com/#json=<id>,<key>" -o output.pptx
# Convert to Lucid Package Format
excalidraw-convert convert-lucid "https://excalidraw.com/#json=<id>,<key>" -o output.lucid
# From a direct JSON / .excalidraw file URL
excalidraw-convert convert "https://raw.githubusercontent.com/you/repo/main/diagram.excalidraw" -o output.pptx
# Append slides to an existing presentation
excalidraw-convert convert "https://..." -o existing.pptx --embed
# Inspect a scene before converting
excalidraw-convert inspect "https://..."
Also callable as a module:
python -m excalidraw_convert convert "https://..." -o output.pptx
python -m excalidraw_convert convert-lucid "https://..." -o output.lucid
Python API
from excalidraw_convert import fetch_scene, convert, convert_to_lucid
scene = fetch_scene("https://excalidraw.com/#json=<id>,<key>")
# PowerPoint
convert(scene, "output.pptx")
# Lucid Package Format
convert_to_lucid(scene, "output.lucid")
# Append to an existing PowerPoint file
convert(scene, "existing.pptx", embed_path="existing.pptx")
# Custom slide dimensions (inches, new files only)
convert(scene, "output.pptx", slide_width=10, slide_height=7.5)
Supported URL formats
| Format | Example |
|---|---|
| Excalidraw share link | https://excalidraw.com/#json=abc123,base64key |
Raw .excalidraw file URL |
https://raw.githubusercontent.com/.../diagram.excalidraw |
| Any URL returning JSON | https://your-server.com/scene.json |
Note on Excalidraw share links: the scene is end-to-end encrypted in the browser. This tool replicates the AES-GCM decryption that the Excalidraw web app performs client-side. If decryption fails for a link, try exporting the scene as a
.excalidrawfile and hosting it somewhere accessible.
Limitations / known gaps
Both formats
- Roughness / hand-drawn style: Excalidraw's sketchy aesthetic is not reproduced — shapes are rendered as clean geometric shapes.
- Hachure fill: approximated as a solid fill.
- Curved / elbow arrows: rendered as straight connectors or straight segments.
freedrawpressures: variable stroke-width pressure data is ignored; a fixed width is used.- Grouped elements: group membership is preserved in rendering order but not as native groups.
- Embeddable / iframe elements: skipped with a warning.
- Fonts: Excalidraw's Virgil hand-drawn font is mapped to Caveat (install it for best results; falls back to the system default).
PowerPoint only
freedrawelements are rendered as freeform polygon paths (not true brush strokes).
Lucid only
freedrawelements are approximated asflexiblePolygonshapes with up to 100 sampled vertices.- Arrow connection points snap to the nearest edge of the target shape.
Development
pip install -e ".[dev]"
pytest tests/ -v
Release files for excalidraw-convert 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| excalidraw_convert-0.1.0.tar.gz | 23.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| excalidraw_convert-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 45.7 kB
Release files / excalidraw_convert-0.1.0.tar.gz
| Download URL | excalidraw_convert-0.1.0.tar.gz |
|---|---|
| Size | 23.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ddba68b1a2ce9297e6e5fb03b1d46b8d4517a93617c9453d875322a1cd7a344d
|
|
BLAKE2b-256 checksum How to use checksums |
348c8811e0461b4fecbe72a89f79bcb47675aded6f9819fef9ad55109cb0b6c9
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|
Release files / excalidraw_convert-0.1.0-py3-none-any.whl
| Download URL | excalidraw_convert-0.1.0-py3-none-any.whl |
|---|---|
| Size | 22.0 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
e629b5e2a77a7951f183eed60072dc96d723ac4102f20e53f546cd7cc588b770
|
|
BLAKE2b-256 checksum How to use checksums |
f0b422fb49b226d7a38542fee3b1894447d0e0d7c55096163c4592c39b5bd5a0
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.14.4
|