Universal diagram converter - the pandoc for diagrams
diacea converts between diagram formats using a format-agnostic intermediate representation. Convert Excalidraw (including Obsidian .excalidraw.md), TLDraw, SVG, Mermaid, or PlantUML diagrams to PlantUML, C4-PlantUML, Mermaid, GraphViz DOT, or D2.
- Visual to Text: Convert hand-drawn diagrams into version-controllable text formats
- Text to Text: Convert between Mermaid, PlantUML/C4, GraphViz DOT, and D2
- Multiple Input Formats: Excalidraw, Obsidian Excalidraw markdown, TLDraw (legacy and v2
.tldr), SVG, Mermaid flowcharts and sequence diagrams, PlantUML (including C4 macros) - Multiple Output Formats: PlantUML, C4-PlantUML, Mermaid, GraphViz DOT, D2
- Semantic Inference: Automatically detects diagram element types (databases, people, systems)
- Agent Friendly:
--jsonenvelopes,inspect/formatssubcommands, and structured exit codes - Docs Integrations:
diacea syncwith pre-commit hooks and an MkDocs plugin keep generated diagrams current - Python Native: Pure Python implementation
pip install diacea
# For Obsidian Excalidraw notes with compressed-json Drawing blocks
pip install 'diacea[obsidian]'# Convert Excalidraw to Mermaid
diacea -i diagram.json -f mermaid -o output.mmd
# Convert to C4-PlantUML
diacea -i diagram.json -f c4 -o architecture.puml
# Convert TLDraw to GraphViz with custom direction
diacea -i tldraw.json -f graphviz --graphviz-direction TB -o output.dot
# Convert an Obsidian Excalidraw note
diacea -i notes/architecture.excalidraw.md -f mermaid
# Convert SVG to D2 with sketch mode
diacea -i diagram.svg -f d2 --d2-sketch -o output.d2
# Text-to-text: Mermaid flowchart to D2, PlantUML to Mermaid
diacea -i flow.mmd -f d2
diacea -i architecture.puml -f mermaid --mermaid-type flowchart
# Pipe from stdin
cat diagram.json | diacea -i - -f mermaid
# Machine-readable output: JSON envelope with the converted text,
# detected formats, per-element semantic inference, and warnings
diacea -i diagram.json -f mermaid --json
# Preview a file before converting (detected format, elements, confidences)
diacea inspect diagram.json --json
# List supported formats and their options
diacea formats --json
# Build a workspace from existing diagram files
diacea-workspace create --name "My System" --from-diagrams a.json b.svg -o workspace.ymldiacea sync regenerates text diagrams next to their sources, writing only when the output is stale:
# Write arch.mmd next to arch.excalidraw (default format: mermaid)
diacea sync docs/diagrams/arch.excalidraw
# Other formats and a dedicated output directory
diacea sync docs/diagrams/*.excalidraw -f d2 --output-dir docs/generated
# CI-friendly: report stale outputs and exit 1 without writing
diacea sync --check docs/diagrams/*.excalidrawThe repo ships diacea-sync (rewrites stale outputs) and diacea-check (fails without writing) hooks:
repos:
- repo: https://github.com/kyleking/diacea
rev: main # prefer a release tag
hooks:
- id: diacea-sync
args: [-f, mermaid]Install diacea[mkdocs] and register the plugin:
plugins:
- diaceaThen reference diagram sources from markdown with a diacea fence, which is replaced at build time by a code block in the target language (so mkdocs-material's Mermaid support renders it):
```diacea
source: diagrams/architecture.excalidraw
format: mermaid
```source is resolved relative to the page, then the docs directory. format defaults to mermaid; mermaid-type optionally forces flowchart, c4, or sequence.
from diacea.parsers import ExcalidrawParser
from diacea.generators import MermaidGenerator, C4PlantUMLGenerator
# Parse input
parser = ExcalidrawParser()
with open('diagram.json') as f:
import json
diagram = parser.parse(json.load(f))
# Generate output
mermaid_gen = MermaidGenerator()
print(mermaid_gen.generate(diagram))
c4_gen = C4PlantUMLGenerator()
print(c4_gen.generate(diagram))| Format | Parser | Auto-detect | Notes |
|---|---|---|---|
| Excalidraw JSON | ExcalidrawParser |
Yes | Scenes and clipboard exports |
Obsidian Excalidraw (.excalidraw.md) |
ExcalidrawParser |
Yes | Compressed notes need the [obsidian] extra |
| TLDraw JSON | TLDrawParser |
Yes | Legacy v1 documents and v2 .tldr files |
| SVG | SVGParser |
Yes | Basic shapes; curves sampled for accurate bounding boxes |
| Mermaid | MermaidParser |
Yes | Flowchart/graph and sequence diagrams; layout synthesized |
| PlantUML | PlantUMLParser |
Yes | Deployment/component elements and C4 macros; layout synthesized |
| Format | Generator | Options |
|---|---|---|
| PlantUML | PlantUMLGenerator |
- |
| C4-PlantUML | C4PlantUMLGenerator |
- |
| Mermaid | MermaidGenerator |
--mermaid-type (flowchart, c4, sequence) |
| GraphViz DOT | GraphVizGenerator |
--graphviz-direction, --graphviz-type |
| D2 | D2Generator |
--d2-direction, --d2-sketch |
Input Formats IR (Intermediate Repr) Output Formats
------------- ---------------------- --------------
Excalidraw --+ +-- PlantUML
TLDraw --+ +--> C4-PlantUML
SVG --+--> Diagram -> Elements -> Semantic +--> Mermaid
Mermaid --+ (with semantic types) +--> GraphViz DOT
PlantUML/C4 --+ +-- D2
- DEVELOPER.md - Development setup and contributing
- SPEC.md - Detailed specifications and use cases
- AGENTS.md - AI assistant guide to the codebase
- procXD - Process diagram converter
- Excalidraw_Interface - Excalidraw integration tools
We welcome pull requests! For your pull request to be accepted smoothly, we suggest that you first open a GitHub issue to discuss your idea. For resources on getting started with the code base, see DEVELOPER.md.
We follow the Contributor Covenant Code of Conduct.
- Documentation: https://diacea.kyleking.me
- PyPI: https://pypi.org/project/diacea
- Repository: https://github.com/kyleking/diacea
- Changelog: docs/docs/CHANGELOG.md