text
1. Understand requirements -> determine diagram type, elements, relationships
2. Generate XML directly -> write drawio XML (read only the relevant section from references/best-practices.md)
3. Self-review (DO NOT SKIP) -> re-read XML and fix any issues found
4. Save .drawio file -> write to user's working directory
5. CLI export -> call draw.io desktop CLI to export image
6. Deliver to user -> show image + provide editable .drawio file
Determine:
You MUST write the XML directly. Do not call any script to generate it.
xml
<?xml version="1.0" encoding="UTF-8"?>
<mxfile host="app.diagrams.net" agent="drawio-skill" version="21.0.0" type="device">
<diagram name="DiagramName" id="diagram-1">
<mxGraphModel dx="1422" dy="762"
grid="1" gridSize="10"
guides="1" tooltips="1" connect="1"
arrows="1" fold="1"
page="1" pageScale="1"
pageWidth="1600" pageHeight="1200"
math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<!-- nodes and edges here -->
</root>
</mxGraphModel>
</diagram>
</mxfile>
xml
<mxCell id="node-1" value="Label"
style="rounded=1;whiteSpace=wrap;html=1;fillColor=#dae8fc;strokeColor=#6c8ebf;fontSize=14;"
vertex="1" parent="1">
<mxGeometry x="100" y="100" width="160" height="60" as="geometry" />
</mxCell>

 inside value, for example value="API
Gateway"\n inside value; draw.io will render it as backslash + n texthtml=1 on nodes, but still use 
 as the default line-break form for predictable outputxml
<mxCell id="edge-1" value=""
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="node-1" target="node-2">
<mxGeometry relative="1" as="geometry" />
</mxCell>
whiteSpace=wrap;html=1; on all nodes so long text wraps instead of overflowingTypeDirectionPrimary axisSpacing (between edges)AlignmentFlowchartTop-to-bottomY increases100px verticalCenter xArchitectureLayered block (preferred)Y increases20px between layersLeft label + container rowsUML SequenceLeft-to-right participantsX increases200px horizontalTop-alignedUML ClassGrid / top-to-bottomY increases100px vertical, 80px horizontalLeft-aligned columnsER DiagramSpread / gridBoth axes120px bothGrid-alignedMindmapCenter-outward radialBoth axes150px from center per levelRadial symmetricNetworkHierarchical layersY increases100px vertical, 120px horizontalCenter each layer
Before finalizing coordinates, verify:
pageWidth in mxGraphModel; for tall ones increase pageHeightUse this formula to center N items horizontally in a row:
text
total_width = N * node_width + (N - 1) * gap
start_x = (pageWidth - total_width) / 2
item[i].x = start_x + i * (node_width + gap)
For vertical centering in a column, apply the same logic to Y axis.
For rows inside a fixed-width container, also check fill density:
text
inner_width = container_width - 2 * side_pad
gap = (inner_width - N * item_width) / (N - 1)
If gap is much larger than the item width, or side padding is much larger than gap, adjust one of:
For incomplete last rows, center the remaining items instead of left-aligning them and leaving a large blank tail.
ElementWidthHeightStandard node16060Decision (rhombus)16080Database (cylinder)14080Actor (UML)4060Start/End (rounded)16060Mindmap center18080Mindmap branch14050Mindmap leaf12040ER table header200variesGroup/containerautoauto
After generating XML, re-read your output and check each item below. If any check fails, fix the XML before proceeding. This step catches the most common rendering bugs — skipping it results in broken diagrams.
Structural checks:
id values are unique across the entire filemxCell with vertex="1" has correct parent (usually "1", but container children use the container ID)source and target reference existing node IDsmxGeometry always has as="geometry" attributeLayout checks (these are the most common failures — actually verify the numbers):
mxGeometry elementStyle checks:
whiteSpace=wrap;html=1; in style
 inside value, never literal \nfontSize=14 or larger for readabilityedgeStyle=orthogonalEdgeStyle for clean routing (except mindmaps which use curved=1)rhombus shape; database nodes use shape=cylinder3Run these commands in order, stop at the first one that succeeds:
bash
# 1. Try PATH first (works if user installed globally)
which draw.io 2>/dev/null || which drawio 2>/dev/null
If that fails, check platform-specific default paths:
macOS:
bash
ls /Applications/draw.io.app/Contents/MacOS/draw.io 2>/dev/null
Windows (bash/MSYS2):
bash
# Check common install locations
ls "/c/Program Files/draw.io/draw.io.exe" 2>/dev/null || \
ls "$LOCALAPPDATA/Programs/draw.io/draw.io.exe" 2>/dev/null
Linux:
bash
ls /usr/bin/drawio 2>/dev/null || ls /snap/bin/drawio 2>/dev/null
Tell the user draw.io is not installed and suggest:
PlatformInstall CommandmacOSbrew install --cask drawioWindowswinget install JGraph.DrawLinuxsnap install drawioAllDownload from https://github.com/jgraph/drawio-desktop/releases
Do NOT auto-install without user confirmation.
Use the detected path (stored as $DRAWIO) to export:
bash
"$DRAWIO" -x -f png --scale 2 -o output.png diagram.drawio
FlagPurpose-xExport mode (no GUI)-f png/svg/pdfOutput format-o pathOutput file path--scale 22x resolution for crisp PNG--border 20Add border padding (px)--width 1600Constrain output width-p 0Export specific page (0-indexed)--cropCrop to diagram content
After export:
ecommerce-order-flow.drawioecommerce-order-flow.pngFor architecture diagrams, use the Layered Block Style — see references/best-practices.md for full templates and layout constants. This is the preferred style: structured block layout with no arrows, horizontal layers, left label column, and optional cross-cutting sidebar.
When the user is not satisfied with the result and asks for modifications:
references/best-practices.md contains:
For other diagram types (flowchart, UML, ER, mindmap, network, etc.), generate appropriate draw.io XML directly based on your knowledge. Read the "General Rules" section for basic formatting guidance.