---
name: utility-drawio
description: Generate draw.io diagrams as .drawio files, optionally export to PNG/SVG/PDF with embedded XML
allowed-tools: Bash, Write
---

# Draw.io Diagram Skill

Generate draw.io diagrams as native `.drawio` files. Optionally export to PNG, SVG, or PDF with the diagram XML embedded (so the exported file remains editable in draw.io).

Original source: https://raw.githubusercontent.com/jgraph/drawio-mcp/refs/heads/main/skill-cli/SKILL.md

## How to create a diagram

1. **Generate draw.io XML** in mxGraphModel format for the requested diagram
2. **Write the XML** to a `.drawio` file in the current working directory using the Write tool
3. **If the user requested an export format** (png, svg, pdf), export using the draw.io CLI with `--embed-diagram`, then delete the source `.drawio` file
4. **Open the result** — the exported file if exported, or the `.drawio` file otherwise

## Choosing the output format

Check the user's request for a format preference. Examples:

- `/drawio create a flowchart` → `flowchart.drawio`
- `/drawio png flowchart for login` → `login-flow.drawio.png`
- `/drawio svg: ER diagram` → `er-diagram.drawio.svg`
- `/drawio pdf architecture overview` → `architecture-overview.drawio.pdf`

If no format is mentioned, just write the `.drawio` file and open it in draw.io. The user can always ask to export later.

### Supported export formats

| Format | Embed XML  | Notes                                    |
| ------ | ---------- | ---------------------------------------- |
| `png`  | Yes (`-e`) | Viewable everywhere, editable in draw.io |
| `svg`  | Yes (`-e`) | Scalable, editable in draw.io            |
| `pdf`  | Yes (`-e`) | Printable, editable in draw.io           |
| `jpg`  | No         | Lossy, no embedded XML support           |

PNG, SVG, and PDF all support `--embed-diagram` — the exported file contains the full diagram XML, so opening it in draw.io recovers the editable diagram.

## draw.io CLI

The draw.io desktop app includes a command-line interface for exporting.

### Locating the CLI

Try `drawio` first (works if on PATH), then fall back to the platform-specific path:

- **macOS**: `/Applications/draw.io.app/Contents/MacOS/draw.io`
- **Linux**: `drawio` (typically on PATH via snap/apt/flatpak)
- **Windows**: `"C:\Program Files\draw.io\draw.io.exe"`

Use `which drawio` (or `where drawio` on Windows) to check if it's on PATH before falling back.

### Export command

```bash
drawio -x -f <format> -e -b 10 -o <output> <input.drawio>
```

Key flags:
- `-x` / `--export`: export mode
- `-f` / `--format`: output format (png, svg, pdf, jpg)
- `-e` / `--embed-diagram`: embed diagram XML in the output (PNG, SVG, PDF only)
- `-o` / `--output`: output file path
- `-b` / `--border`: border width around diagram (default: 0)
- `-t` / `--transparent`: transparent background (PNG only)
- `-s` / `--scale`: scale the diagram size
- `--width` / `--height`: fit into specified dimensions (preserves aspect ratio)
- `-a` / `--all-pages`: export all pages (PDF only)
- `-p` / `--page-index`: select a specific page (1-based)

### Opening the result

- **macOS**: `open <file>`
- **Linux**: `xdg-open <file>`
- **Windows**: `start <file>`

## File naming

- Use a descriptive filename based on the diagram content (e.g., `login-flow`, `database-schema`)
- Use lowercase with hyphens for multi-word names
- For export, use double extensions: `name.drawio.png`, `name.drawio.svg`, `name.drawio.pdf` — this signals the file contains embedded diagram XML
- After a successful export, delete the intermediate `.drawio` file — the exported file contains the full diagram

## XML format

A `.drawio` file is native mxGraphModel XML. Always generate XML directly — Mermaid and CSV formats require server-side conversion and cannot be saved as native files.

### Basic structure

Every diagram must have this structure:

```xml
<mxGraphModel>
  <root>
    <mxCell id="0"/>
    <mxCell id="1" parent="0"/>
    <!-- Diagram cells go here with parent="1" -->
  </root>
</mxGraphModel>
```

- Cell `id="0"` is the root layer
- Cell `id="1"` is the default parent layer
- All diagram elements use `parent="1"` unless using multiple layers

### Common styles

**Rounded rectangle:**
```xml
<mxCell id="2" value="Label" style="rounded=1;whiteSpace=wrap;" vertex="1" parent="1">
  <mxGeometry x="100" y="100" width="120" height="60" as="geometry"/>
</mxCell>
```

**Diamond (decision):**
```xml
<mxCell id="3" value="Condition?" style="rhombus;whiteSpace=wrap;" vertex="1" parent="1">
  <mxGeometry x="100" y="200" width="120" height="80" as="geometry"/>
</mxCell>
```

**Arrow (edge):**
```xml
<mxCell id="4" value="" style="edgeStyle=orthogonalEdgeStyle;" edge="1" source="2" target="3" parent="1">
  <mxGeometry relative="1" as="geometry"/>
</mxCell>
```

**Labeled arrow:**
```xml
<mxCell id="5" value="Yes" style="edgeStyle=orthogonalEdgeStyle;" edge="1" source="3" target="6" parent="1">
  <mxGeometry relative="1" as="geometry"/>
</mxCell>
```

### Useful style properties

| Property                           | Values        | Use for                |
| ---------------------------------- | ------------- | ---------------------- |
| `rounded=1`                        | 0 or 1        | Rounded corners        |
| `whiteSpace=wrap`                  | wrap          | Text wrapping          |
| `fillColor=#dae8fc`                | Hex color     | Background color       |
| `strokeColor=#6c8ebf`              | Hex color     | Border color           |
| `fontColor=#333333`                | Hex color     | Text color             |
| `shape=cylinder3`                  | shape name    | Database cylinders     |
| `shape=mxgraph.flowchart.document` | shape name    | Document shapes        |
| `ellipse`                          | style keyword | Circles/ovals          |
| `rhombus`                          | style keyword | Diamonds               |
| `edgeStyle=orthogonalEdgeStyle`    | style keyword | Right-angle connectors |
| `edgeStyle=elbowEdgeStyle`         | style keyword | Elbow connectors       |
| `dashed=1`                         | 0 or 1        | Dashed lines           |
| `swimlane`                         | style keyword | Swimlane containers    |

## CRITICAL: Edge routing - avoid overlapping shapes

Edges MUST NOT cross over unrelated shapes. This is the most common layout problem and must be actively prevented.

### Waypoints

Add explicit waypoints (`mxPoint`) to route edges around obstacles:

```xml
<mxCell id="10" value="" style="edgeStyle=orthogonalEdgeStyle;" edge="1" source="2" target="8" parent="1">
  <mxGeometry relative="1" as="geometry">
    <Array as="points">
      <mxPoint x="50" y="400"/>
      <mxPoint x="50" y="600"/>
    </Array>
  </mxGeometry>
</mxCell>
```

The `Array as="points"` contains intermediate coordinates the edge must pass through, allowing it to detour around intervening shapes.

### When to add waypoints

Before generating each edge, mentally trace its path from source to target:
1. Identify all shapes that lie between source and target
2. If the straight/orthogonal path would cross any shape, add waypoints to route around it
3. Route edges through empty "corridors" between shapes, or around the outer perimeter of shape groups

### Routing strategies

- **Route around the outside**: When an edge must travel past intermediate shapes, route it along the outer edge of the diagram area (left/right/top/bottom margins)
- **Use routing channels**: Leave 60-80px gaps between rows/columns of shapes specifically for edge routing
- **Stagger parallel edges**: When multiple edges share a similar path, offset them by 20-30px to prevent overlap
- **Exit/entry direction**: Use `exitX`, `exitY`, `entryX`, `entryY` (0-1 range) to control which side of a shape an edge connects to, making it easier to avoid crossings

```xml
<mxCell id="11" value="" style="edgeStyle=orthogonalEdgeStyle;exitX=0;exitY=0.5;entryX=0;entryY=0.5;" edge="1" source="2" target="8" parent="1">
  <mxGeometry relative="1" as="geometry">
    <Array as="points">
      <mxPoint x="40" y="180"/>
      <mxPoint x="40" y="580"/>
    </Array>
  </mxGeometry>
</mxCell>
```

### Jump style (fallback for unavoidable crossings)

When crossings are truly unavoidable, add visual indicators:

```xml
style="edgeStyle=orthogonalEdgeStyle;jumpStyle=arc;jumpSize=10;"
```

| Jump style        | Effect                       |
| ----------------- | ---------------------------- |
| `jumpStyle=arc`   | Small arc at crossing points |
| `jumpStyle=gap`   | Gap at crossing points       |
| `jumpStyle=sharp` | Sharp angle at crossings     |

### Layout planning guidelines

To minimize edge crossings from the start:

1. **Plan the layout before writing XML** - sketch the node positions mentally, ensuring data flows in a consistent direction (left-to-right or top-to-bottom)
2. **Allocate routing corridors** - leave 60-80px empty channels between rows/columns of shapes for edges to pass through
3. **Place closely connected nodes adjacent** - nodes with direct edges should be neighbors, not separated by other nodes
4. **Group related nodes** - use spatial clustering so edges between groups travel along the periphery
5. **Minimum spacing** - maintain at least 100px between unconnected shapes to provide routing space

## CRITICAL: XML well-formedness

- **NEVER use double hyphens (`--`) inside XML comments.** `--` is illegal inside `<!-- -->` per the XML spec and causes parse errors. Use single hyphens or rephrase.
- Escape special characters in attribute values: `&amp;`, `&lt;`, `&gt;`, `&quot;`
- Always use unique `id` values for each `mxCell`
