Draw.io Diagrams
Overview
Generate .drawio XML files and export to PNG/SVG/PDF/JPG locally using the native draw.io desktop app CLI.
Supported formats: PNG, SVG, PDF, JPG — no browser automation needed.
When to Use
Explicit triggers: user says "画图", "diagram", "visualize", "flowchart", "draw", "架构图", "流程图"
Proactive triggers:
- Explaining a system with 3+ interacting components
- Describing a multi-step process or decision tree
- Comparing architectures or approaches side by side
Skip when: a simple list or table suffices, or user is in a quick Q&A flow
Prerequisites
The draw.io desktop app must be installed and the CLI accessible:
# macOS (Homebrew — recommended)
brew install --cask drawio
draw.io --version
# macOS (full path if not in PATH)
/Applications/draw.io.app/Contents/MacOS/draw.io --version
# Windows
"C:\Program Files\draw.io\draw.io.exe" --version
# Linux
draw.io --version
Install draw.io desktop if missing:
- macOS:
brew install --cask drawioor download from https://github.com/jgraph/drawio-desktop/releases - Windows: download installer from https://github.com/jgraph/drawio-desktop/releases
- Linux: download
.deb/.rpmfrom https://github.com/jgraph/drawio-desktop/releases
Workflow
- Check deps — verify
draw.io --versionsucceeds; note platform for correct CLI path - Plan — identify shapes, relationships, layout (LR or TB), group by tier/layer
- Generate — write
.drawioXML file to disk (output dir same as user's working dir) - Export draft — run CLI to produce PNG for preview
- Self-check — read the exported PNG, catch obvious issues, auto-fix before showing user
- Review loop — show image to user, collect feedback, apply targeted XML edits, re-export, repeat until approved
- Final export — export approved version to all requested formats, report file paths
Step 5: Self-Check
After exporting the draft PNG, read the image and check for these issues before showing the user:
| Check | What to look for | Auto-fix action |
|---|---|---|
| Overlapping shapes | Two or more shapes stacked on top of each other | Shift shapes apart by ≥200px |
| Clipped labels | Text cut off at shape boundaries | Increase shape width/height to fit label |
| Missing connections | Arrows that don't visually connect to shapes | Verify source/target ids match existing cells |
| Off-canvas shapes | Shapes at negative coordinates or far from the main group | Move to positive coordinates near the cluster |
| Edge-shape overlap | An edge/arrow visually crosses through an unrelated shape | Add waypoints (<Array as="points">) to route around the shape, or increase spacing between shapes |
| Stacked edges | Multiple edges overlap each other on the same path | Distribute entry/exit points across the shape perimeter (use different exitX/entryX values) |
- Max 2 self-check rounds — if issues remain after 2 fixes, show the user anyway
- Re-export after each fix and re-read the new PNG
Step 6: Review Loop
After self-check, show the exported image and ask the user for feedback.
Targeted edit rules — for each type of feedback, apply the minimal XML change:
| User request | XML edit action |
|---|---|
| Change color of X | Find mxCell by value matching X, update fillColor/strokeColor in style |
| Add a new node | Append a new mxCell vertex with next available id, position near related nodes |
| Remove a node | Delete the mxCell vertex and any edges with matching source/target |
| Move shape X | Update x/y in the mxGeometry of the matching mxCell |
| Resize shape X | Update width/height in the mxGeometry of the matching mxCell |
| Add arrow from A to B | Append a new mxCell edge with source/target matching A and B ids |
| Change label text | Update the value attribute of the matching mxCell |
| Change layout direction | Full regeneration — rebuild XML with new orientation |
Rules:
- For single-element changes: edit existing XML in place — preserves layout tuning from prior iterations
- For layout-wide changes (e.g., swap LR↔TB, "start over"): regenerate full XML
- Overwrite the same
{name}.pngeach iteration — do not createv1,v2,v3files - After applying edits, re-export and show the updated image
- Loop continues until user says approved / done / LGTM / 完成
- Safety valve: after 5 iteration rounds, suggest the user open the
.drawiofile in draw.io desktop for fine-grained adjustments
Step 7: Final Export
Once the user approves:
- Export to all requested formats (PNG, SVG, PDF, JPG) — default to PNG if not specified
- Report file paths for both the
.drawiosource file and exported image(s) - Confirm files are saved and ready to use
Draw.io XML Structure
File skeleton
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="drawio" version="26.0.0">
<diagram name="Page-1">
<mxGraphModel>
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- user shapes start at id="2" -->
</root>
</mxGraphModel>
</diagram>
</mxfile>
Rules:
id="0"andid="1"are required root cells — never omit them- User shapes start at
id="2"and increment sequentially - All shapes have
parent="1" - All text uses
html=1in style for proper rendering
Shape types (vertex)
| Style keyword | Use for |
|---|---|
rounded=0 | plain rectangle (default) |
rounded=1 | rounded rectangle — services, modules |
ellipse; | circles/ovals — start/end, databases |
rhombus; | diamond — decision points |
shape=mxgraph.aws4.resourceIcon; | AWS icons |
shape=cylinder3; | cylinder — databases |
swimlane; | group/container with title bar |
Required properties
<!-- Rectangle / rounded box -->
<mxCell id="2" value="Label" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;" vertex="1" parent="1">
<mxGeometry x="100" y="100" width="160" height="60" as="geometry" />
</mxCell>
<!-- Cylinder (database) -->
<mxCell id="3" value="DB" style="shape=cylinder3;whiteSpace=wrap;html=1;fillColor=#f5f5f5;strokeColor=#666666;fontColor=#333333;" vertex="1" parent="1">
<mxGeometry x="350" y="100" width="120" height="80" as="geometry" />
</mxCell>
<!-- Diamond (decision) -->
<mxCell id="4" value="Check?" style="rhombus;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=#d6b656;" vertex="1" parent="1">
<mxGeometry x="100" y="220" width="160" height="80" as="geometry" />
</mxCell>
Connector (edge)
<!-- Directed arrow — always include rounded, orthogonalLoop, jettySize for clean routing -->
<mxCell id="10" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="2" target="3">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Arrow with label + explicit entry/exit points to control direction -->
<mxCell id="11" value="HTTP/REST" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="4">
<mxGeometry relative="1" as="geometry" />
</mxCell>
<!-- Arrow with waypoints — use when edge must route around other shapes -->
<mxCell id="12" value="" style="edgeStyle=orthogonalEdgeStyle;rounded=1;orthogonalLoop=1;jettySize=auto;html=1;" edge="1" parent="1" source="3" target="5">
<mxGeometry relative="1" as="geometry">
<Array as="points">
<mxPoint x="500" y="50" />
</Array>
</mxGeometry>
</mxCell>
Edge style rules:
- Always include
rounded=1;orthogonalLoop=1;jettySize=auto— these enable smart routing that avoids overlaps - Pin
exitX/exitY/entryX/entryYon every edge when a node has 2+ connections — distributes lines across the shape perimeter - Add
<Array as="points">waypoints when an edge must detour around an intermediate shape
Distributing connections on a shape
When multiple edges connect to the same shape, assign different entry/exit points to prevent stacking:
| Position | exitX/entryX | exitY/entryY | Use when |
|---|---|---|---|
| Top center | 0.5 | 0 | connecting to node above |
| Top-left | 0.25 | 0 | 2nd connection from top |
| Top-right | 0.75 | 0 | 3rd connection from top |
| Right center | 1 | 0.5 | connecting to node on right |
| Bottom center | 0.5 | 1 | connecting to node below |
| Left center | 0 | 0.5 | connecting to node on left |
Rule: if a shape has N connections on one side, space them evenly (e.g., 3 connections on bottom → exitX = 0.25, 0.5, 0.75)
Color palette (fillColor / strokeColor)
| Color name | fillColor | strokeColor | Use for |
|---|---|---|---|
| Blue | #dae8fc | #6c8ebf | services, clients |
| Green | #d5e8d4 | #82b366 | success, databases |
| Yellow | #fff2cc | #d6b656 | queues, decisions |
| Orange | #ffe6cc | #d79b00 | gateways, APIs |
| Red/Pink | #f8cecc | #b85450 | errors, alerts |
| Grey | #f5f5f5 | #666666 | external/neutral |
| Purple | #e1d5e7 | #9673a6 | security, auth |
Layout tips
Spacing — scale with complexity:
| Diagram complexity | Nodes | Horizontal gap | Vertical gap |
|---|---|---|---|
| Simple | ≤5 | 200px | 150px |
| Medium | 6–10 | 280px | 200px |
| Complex | >10 | 350px | 250px |
Routing corridors: between shape rows/columns, leave an extra ~80px empty corridor where edges can route without crossing shapes. Never place a shape in a gap that edges need to traverse.
General rules:
- Plan a grid before assigning x/y coordinates — sketch node positions on paper/mentally first
- Group related nodes in the same horizontal or vertical band
- Use
swimlanecells for logical grouping with visible borders - Place heavily-connected "hub" nodes centrally so edges radiate outward instead of crossing
- To force straight vertical connections, pin entry/exit points explicitly on edges:
exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0 - Always center-align a child node under its parent (same center x) to avoid diagonal routing
- Event bus pattern: place Kafka/bus nodes in the center of the service row, not below — services on either side can reach it with short horizontal arrows (
exitX=1left side,exitX=0right side), eliminating all line crossings - Horizontal connections (
exitX=1orexitX=0) never cross vertical nodes in the same row; use them for peer-to-peer and publish connections
Avoiding edge-shape overlap:
- Before finalizing coordinates, trace each edge path mentally — if it must cross an unrelated shape, either move the shape or add waypoints
- For tree/hierarchical layouts: assign nodes to layers (rows), connect only between adjacent layers to minimize crossings
- For star/hub layouts: place the hub center, satellites around it — edges stay short and radial
- When an edge must span multiple rows/columns, route it along the outer corridor, not through the middle of the diagram
Export
Commands
# macOS — Homebrew (draw.io in PATH)
draw.io -x -f png -s 2 -o diagram.png input.drawio
# macOS — full path (if not in PATH)
/Applications/draw.io.app/Contents/MacOS/draw.io -x -f png -s 2 -o diagram.png input.drawio
# Windows
"C:\Program Files\draw.io\draw.io.exe" -x -f png -s 2 -o diagram.png input.drawio
# Linux (headless — requires xvfb-run)
xvfb-run -a draw.io -x -f png -s 2 -o diagram.png input.drawio
# SVG export
draw.io -x -f svg -o diagram.svg input.drawio
# PDF export
draw.io -x -f pdf -o diagram.pdf input.drawio
Key flags:
-x— export mode (required)-f— format:png,svg,pdf,jpg-s— scale:1,2,3(2 recommended for PNG)-o— output file path--page-index 0— export specific page (default: all)
Checking if draw.io is in PATH
# Try short command first
if command -v draw.io &>/dev/null; then
DRAWIO="draw.io"
elif [ -f "/Applications/draw.io.app/Contents/MacOS/draw.io" ]; then
DRAWIO="/Applications/draw.io.app/Contents/MacOS/draw.io"
else
echo "draw.io not found — install from https://github.com/jgraph/drawio-desktop/releases"
fi
Common Mistakes
| Mistake | Fix |
|---|---|
Missing id="0" and id="1" root cells | Always include both at the top of <root> |
| Shapes not connected | source and target on edge must match existing shape id values |
| Export command not found on macOS | Try full path /Applications/draw.io.app/Contents/MacOS/draw.io |
| Linux: blank/error output headlessly | Prefix command with xvfb-run -a |
| PDF export fails | Ensure Chromium is available (draw.io bundles it on desktop) |
| Background color wrong in CLI export | Known CLI bug; add --transparent flag or set background via style |
| Overlapping shapes | Scale spacing with complexity (200–350px); leave routing corridors |
| Edges crossing through shapes | Add waypoints, distribute entry/exit points, or increase spacing |
Special characters in value | Use XML entities: & < > " |
| Iteration loop never ends | After 5 rounds, suggest user open .drawio in draw.io desktop for fine-tuning |