|
| 1 | +# draw.io XML Schema Reference |
| 2 | + |
| 3 | +Complete reference for the `.drawio` file format (mxGraph XML). Use this when generating, parsing, or validating diagram files. |
| 4 | + |
| 5 | +--- |
| 6 | + |
| 7 | +## Top-Level Structure |
| 8 | + |
| 9 | +Every `.drawio` file is XML with this root structure: |
| 10 | + |
| 11 | +```xml |
| 12 | +<!-- Set modified to the current ISO 8601 timestamp when generating a new file --> |
| 13 | +<mxfile host="Electron" modified="" |
| 14 | + agent="draw.io" version="26.0.0" type="device"> |
| 15 | + <diagram id="<unique-id>" name="<Page Name>"> |
| 16 | + <mxGraphModel ...attributes...> |
| 17 | + <root> |
| 18 | + <mxCell id="0" /> |
| 19 | + <mxCell id="1" parent="0" /> |
| 20 | + <!-- All content cells here --> |
| 21 | + </root> |
| 22 | + </mxGraphModel> |
| 23 | + </diagram> |
| 24 | +</mxfile> |
| 25 | +``` |
| 26 | + |
| 27 | +### `<mxfile>` Attributes |
| 28 | + |
| 29 | +| Attribute | Required | Default | Description | |
| 30 | +| ----------- | ---------- | --------- | ------------- | |
| 31 | +| `host` | No | `"app.diagrams.net"` | Origin editor (`"Electron"` for desktop/VS Code) | |
| 32 | +| `modified` | No | — | ISO 8601 timestamp | |
| 33 | +| `agent` | No | — | User agent string | |
| 34 | +| `version` | No | — | draw.io version | |
| 35 | +| `type` | No | `"device"` | Storage type | |
| 36 | + |
| 37 | +### `<diagram>` Attributes |
| 38 | + |
| 39 | +| Attribute | Required | Description | |
| 40 | +| ----------- | ---------- | ------------- | |
| 41 | +| `id` | Yes | Unique page identifier (any string) | |
| 42 | +| `name` | Yes | Tab label shown in editor | |
| 43 | + |
| 44 | +### `<mxGraphModel>` Attributes |
| 45 | + |
| 46 | +| Attribute | Type | Default | Description | |
| 47 | +| ----------- | ------ | --------- | ------------- | |
| 48 | +| `dx` | int | `1422` | Scroll X offset | |
| 49 | +| `dy` | int | `762` | Scroll Y offset | |
| 50 | +| `grid` | `0`/`1` | `1` | Show grid | |
| 51 | +| `gridSize` | int | `10` | Grid snap size in px | |
| 52 | +| `guides` | `0`/`1` | `1` | Show alignment guides | |
| 53 | +| `tooltips` | `0`/`1` | `1` | Enable tooltips | |
| 54 | +| `connect` | `0`/`1` | `1` | Enable connection arrows on hover | |
| 55 | +| `arrows` | `0`/`1` | `1` | Show directional arrows | |
| 56 | +| `fold` | `0`/`1` | `1` | Enable group fold/collapse | |
| 57 | +| `page` | `0`/`1` | `1` | Show page boundary | |
| 58 | +| `pageScale` | float | `1` | Page zoom scale | |
| 59 | +| `pageWidth` | int | `1169` | Page width in px (A4 landscape) | |
| 60 | +| `pageHeight` | int | `827` | Page height in px (A4 landscape) | |
| 61 | +| `math` | `0`/`1` | `0` | Enable LaTeX math rendering | |
| 62 | +| `shadow` | `0`/`1` | `0` | Global shadow on shapes | |
| 63 | + |
| 64 | +**Common page sizes (px at 96dpi):** |
| 65 | + |
| 66 | +| Format | Width | Height | |
| 67 | +| -------- | ------- | -------- | |
| 68 | +| A4 landscape | `1169` | `827` | |
| 69 | +| A4 portrait | `827` | `1169` | |
| 70 | +| A3 landscape | `1654` | `1169` | |
| 71 | +| Letter landscape | `1100` | `850` | |
| 72 | +| Letter portrait | `850` | `1100` | |
| 73 | +| Screen (16:9) | `1654` | `931` | |
| 74 | + |
| 75 | +--- |
| 76 | + |
| 77 | +## Reserved Cells (Always Required) |
| 78 | + |
| 79 | +```xml |
| 80 | +<mxCell id="0" /> <!-- Root cell — never omit, never add attributes --> |
| 81 | +<mxCell id="1" parent="0" /> <!-- Default layer — all cells are children of this --> |
| 82 | +``` |
| 83 | + |
| 84 | +These two cells MUST be the first entries inside `<root>`. IDs `0` and `1` are reserved and must not be used for any other cell. |
| 85 | + |
| 86 | +--- |
| 87 | + |
| 88 | +## Vertex (Shape) Element |
| 89 | + |
| 90 | +```xml |
| 91 | +<mxCell |
| 92 | + id="2" |
| 93 | + value="Label Text" |
| 94 | + style="rounded=1;whiteSpace=wrap;html=1;" |
| 95 | + vertex="1" |
| 96 | + parent="1"> |
| 97 | + <mxGeometry x="200" y="160" width="120" height="60" as="geometry" /> |
| 98 | +</mxCell> |
| 99 | +``` |
| 100 | + |
| 101 | +### `<mxCell>` Vertex Attributes |
| 102 | + |
| 103 | +| Attribute | Required | Type | Description | |
| 104 | +| ----------- | ---------- | ------ | ------------- | |
| 105 | +| `id` | Yes | string | Unique identifier within this diagram | |
| 106 | +| `value` | Yes | string | Label text (HTML allowed if style has `html=1`) | |
| 107 | +| `style` | Yes | string | Semicolon-delimited key=value style string | |
| 108 | +| `vertex` | Yes | `"1"` | Must be `"1"` to declare this as a shape | |
| 109 | +| `parent` | Yes | string | Parent cell ID (`"1"` for default layer) | |
| 110 | + |
| 111 | +### `<mxGeometry>` Vertex Attributes |
| 112 | + |
| 113 | +| Attribute | Required | Type | Description | |
| 114 | +| ----------- | ---------- | ------ | ------------- | |
| 115 | +| `x` | Yes | float | Left edge of shape (px from canvas origin) | |
| 116 | +| `y` | Yes | float | Top edge of shape (px from canvas origin) | |
| 117 | +| `width` | Yes | float | Shape width in px | |
| 118 | +| `height` | Yes | float | Shape height in px | |
| 119 | +| `as` | Yes | `"geometry"` | Always `"geometry"` | |
| 120 | + |
| 121 | +--- |
| 122 | + |
| 123 | +## Edge (Connector) Element |
| 124 | + |
| 125 | +```xml |
| 126 | +<mxCell |
| 127 | + id="5" |
| 128 | + value="Label" |
| 129 | + style="edgeStyle=orthogonalEdgeStyle;rounded=0;html=1;" |
| 130 | + edge="1" |
| 131 | + source="2" |
| 132 | + target="3" |
| 133 | + parent="1"> |
| 134 | + <mxGeometry relative="1" as="geometry" /> |
| 135 | +</mxCell> |
| 136 | +``` |
| 137 | + |
| 138 | +### `<mxCell>` Edge Attributes |
| 139 | + |
| 140 | +| Attribute | Required | Type | Description | |
| 141 | +| ----------- | ---------- | ------ | ------------- | |
| 142 | +| `id` | Yes | string | Unique identifier | |
| 143 | +| `value` | Yes | string | Connector label (empty string for no label) | |
| 144 | +| `style` | Yes | string | Style string (see Edge Styles) | |
| 145 | +| `edge` | Yes | `"1"` | Must be `"1"` to declare as connector | |
| 146 | +| `source` | No | string | ID of source vertex | |
| 147 | +| `target` | No | string | ID of target vertex | |
| 148 | +| `parent` | Yes | string | Parent cell ID (usually `"1"`) | |
| 149 | + |
| 150 | +### `<mxGeometry>` Edge Attributes |
| 151 | + |
| 152 | +| Attribute | Required | Type | Description | |
| 153 | +| ----------- | ---------- | ------ | ------------- | |
| 154 | +| `relative` | No | `"1"` | Always `"1"` for edges | |
| 155 | +| `as` | Yes | `"geometry"` | Always `"geometry"` | |
| 156 | + |
| 157 | +### Edge with Label Offset |
| 158 | + |
| 159 | +```xml |
| 160 | +<mxGeometry x="-0.1" y="10" relative="1" as="geometry"> |
| 161 | + <mxPoint as="offset" /> |
| 162 | +</mxGeometry> |
| 163 | +``` |
| 164 | + |
| 165 | +The `x` on relative geometry moves the label along the edge (-1 to 1). `y` is perpendicular offset in px. |
| 166 | + |
| 167 | +### Edge with Manual Waypoints (Control Points) |
| 168 | + |
| 169 | +```xml |
| 170 | +<mxGeometry relative="1" as="geometry"> |
| 171 | + <Array as="points"> |
| 172 | + <mxPoint x="340" y="80" /> |
| 173 | + <mxPoint x="340" y="200" /> |
| 174 | + </Array> |
| 175 | +</mxGeometry> |
| 176 | +``` |
| 177 | + |
| 178 | +--- |
| 179 | + |
| 180 | +## Multi-Page Diagrams |
| 181 | + |
| 182 | +```xml |
| 183 | +<mxfile> |
| 184 | + <diagram id="page-1" name="Overview"> |
| 185 | + <mxGraphModel>...</mxGraphModel> |
| 186 | + </diagram> |
| 187 | + <diagram id="page-2" name="Detail"> |
| 188 | + <mxGraphModel>...</mxGraphModel> |
| 189 | + </diagram> |
| 190 | +</mxfile> |
| 191 | +``` |
| 192 | + |
| 193 | +Each `<diagram>` is a separate page/tab. Cell IDs are scoped to their own `<diagram>` — the same ID value can appear in different pages without conflict. |
| 194 | + |
| 195 | +--- |
| 196 | + |
| 197 | +## Layer Cells |
| 198 | + |
| 199 | +Layers replace the default `id="1"` layer. Cells are assigned to a layer via `parent`: |
| 200 | + |
| 201 | +```xml |
| 202 | +<mxCell id="0" /> |
| 203 | +<mxCell id="1" value="Background" parent="0" /> <!-- layer 1 --> |
| 204 | +<mxCell id="layer2" value="Services" parent="0" /> <!-- layer 2 --> |
| 205 | +<mxCell id="layer3" value="Connectors" parent="0" /> <!-- layer 3 --> |
| 206 | + |
| 207 | +<!-- Assign layer via parent attribute --> |
| 208 | +<mxCell id="10" value="API" ... parent="layer2"> |
| 209 | + <mxGeometry ... /> |
| 210 | +</mxCell> |
| 211 | +``` |
| 212 | + |
| 213 | +Toggle layer visibility: |
| 214 | + |
| 215 | +```xml |
| 216 | +<mxCell id="layer2" value="Services" parent="0" visible="0" /> |
| 217 | +``` |
| 218 | + |
| 219 | +--- |
| 220 | + |
| 221 | +## Swimlane Container |
| 222 | + |
| 223 | +```xml |
| 224 | +<!-- Swimlane container --> |
| 225 | +<mxCell id="swim1" value="Process" style="shape=pool;startSize=30;horizontal=1;" |
| 226 | + vertex="1" parent="1"> |
| 227 | + <mxGeometry x="40" y="40" width="800" height="340" as="geometry" /> |
| 228 | +</mxCell> |
| 229 | + |
| 230 | +<!-- Lane 1 (child of swimlane container) --> |
| 231 | +<mxCell id="lane1" value="Customer" style="swimlane;startSize=30;" |
| 232 | + vertex="1" parent="swim1"> |
| 233 | + <mxGeometry x="0" y="30" width="800" height="150" as="geometry" /> |
| 234 | +</mxCell> |
| 235 | + |
| 236 | +<!-- Shape inside lane (child of lane) --> |
| 237 | +<mxCell id="step1" value="Place Order" style="rounded=1;whiteSpace=wrap;html=1;" |
| 238 | + vertex="1" parent="lane1"> |
| 239 | + <mxGeometry x="80" y="50" width="120" height="60" as="geometry" /> |
| 240 | +</mxCell> |
| 241 | +``` |
| 242 | + |
| 243 | +> **Key**: Cells inside a swimlane have `parent` set to the **lane's ID**, not `"1"`. |
| 244 | +> Coordinates inside lanes are **relative to the lane origin**. |
| 245 | +
|
| 246 | +--- |
| 247 | + |
| 248 | +## Group Cells |
| 249 | + |
| 250 | +```xml |
| 251 | +<!-- Invisible group container --> |
| 252 | +<mxCell id="group1" value="" style="group;" vertex="1" parent="1"> |
| 253 | + <mxGeometry x="100" y="100" width="300" height="200" as="geometry" /> |
| 254 | +</mxCell> |
| 255 | + |
| 256 | +<!-- Children relative to group origin --> |
| 257 | +<mxCell id="child1" value="A" style="rounded=1;" vertex="1" parent="group1"> |
| 258 | + <mxGeometry x="20" y="20" width="100" height="60" as="geometry" /> |
| 259 | +</mxCell> |
| 260 | +``` |
| 261 | + |
| 262 | +--- |
| 263 | + |
| 264 | +## HTML Labels |
| 265 | + |
| 266 | +When `html=1` is in the style, `value` can contain HTML: |
| 267 | + |
| 268 | +```xml |
| 269 | +<mxCell value="<b>OrderService</b><br><i>:8080</i>" |
| 270 | + style="rounded=1;html=1;" vertex="1" parent="1"> |
| 271 | + <mxGeometry x="100" y="100" width="160" height="60" as="geometry" /> |
| 272 | +</mxCell> |
| 273 | +``` |
| 274 | + |
| 275 | +HTML must be XML-escaped: |
| 276 | + |
| 277 | +- `<` → `<` |
| 278 | +- `>` → `>` |
| 279 | +- `&` → `&` |
| 280 | +- `"` → `"` |
| 281 | + |
| 282 | +Common HTML tags supported: `<b>`, `<i>`, `<u>`, `<br>`, `<font color="#hex">`, `<span style="...">`, `<hr/>` |
| 283 | + |
| 284 | +--- |
| 285 | + |
| 286 | +## Tooltip / Metadata |
| 287 | + |
| 288 | +```xml |
| 289 | +<mxCell value="Service Name" tooltip="Handles order processing" style="..." vertex="1" parent="1"> |
| 290 | + <mxGeometry ... /> |
| 291 | +</mxCell> |
| 292 | +``` |
| 293 | + |
| 294 | +--- |
| 295 | + |
| 296 | +## ID Generation Rules |
| 297 | + |
| 298 | +| Rule | Detail | |
| 299 | +| ------ | -------- | |
| 300 | +| IDs `0` and `1` | Reserved — always the root and default layer | |
| 301 | +| All other IDs | Must be unique within their `<diagram>` | |
| 302 | +| Safe pattern | Sequential integers starting at `2`, or UUID strings | |
| 303 | +| Cross-page | IDs do not need to be unique across different `<diagram>` pages | |
| 304 | + |
| 305 | +**Safe sequential ID example:** |
| 306 | + |
| 307 | +```text |
| 308 | +id="2", id="3", id="4", ... |
| 309 | +``` |
| 310 | + |
| 311 | +**UUID-style example:** |
| 312 | + |
| 313 | +```text |
| 314 | +id="a1b2c3d4-e5f6-7890-abcd-ef1234567890" |
| 315 | +``` |
| 316 | + |
| 317 | +--- |
| 318 | + |
| 319 | +## Coordinate System |
| 320 | + |
| 321 | +- Origin `(0, 0)` is **top-left** of the canvas |
| 322 | +- `x` increases **rightward** |
| 323 | +- `y` increases **downward** |
| 324 | +- All units are **pixels** |
| 325 | + |
| 326 | +--- |
| 327 | + |
| 328 | +## Recommended Spacing |
| 329 | + |
| 330 | +| Context | Value | |
| 331 | +| --------- | ------- | |
| 332 | +| Minimum gap between shapes | `40px` | |
| 333 | +| Comfortable gap | `80px` | |
| 334 | +| Swimlane inner padding | `20px` | |
| 335 | +| Page margin from edge | `40px` | |
| 336 | +| Connector routing clearance | `10px` | |
| 337 | + |
| 338 | +--- |
| 339 | + |
| 340 | +## Minimal Valid `.drawio` File |
| 341 | + |
| 342 | +```xml |
| 343 | +<mxfile host="Electron" modified="2026-03-25T00:00:00.000Z" version="26.0.0"> |
| 344 | + <diagram id="main" name="Page-1"> |
| 345 | + <mxGraphModel dx="1422" dy="762" grid="1" gridSize="10" guides="1" |
| 346 | + tooltips="1" connect="1" arrows="1" fold="1" |
| 347 | + page="1" pageScale="1" pageWidth="1169" pageHeight="827" |
| 348 | + math="0" shadow="0"> |
| 349 | + <root> |
| 350 | + <mxCell id="0" /> |
| 351 | + <mxCell id="1" parent="0" /> |
| 352 | + </root> |
| 353 | + </mxGraphModel> |
| 354 | + </diagram> |
| 355 | +</mxfile> |
| 356 | +``` |
| 357 | + |
| 358 | +--- |
| 359 | + |
| 360 | +## Validation Rules |
| 361 | + |
| 362 | +### Must Pass |
| 363 | + |
| 364 | +- [ ] `id="0"` and `id="1"` cells always present as first two children of `<root>` |
| 365 | +- [ ] No other cell uses `id="0"` or `id="1"` |
| 366 | +- [ ] All `id` values are unique within each `<diagram>` |
| 367 | +- [ ] Every `<mxCell>` has exactly one `<mxGeometry>` child |
| 368 | +- [ ] `<mxGeometry>` has `as="geometry"` attribute |
| 369 | +- [ ] Vertex cells have `vertex="1"`, edge cells have `edge="1"` |
| 370 | +- [ ] Edge `source`/`target` IDs reference existing vertex IDs in the same diagram |
| 371 | +- [ ] Swimlane children have `parent` set to the swimlane/lane ID, not `"1"` |
| 372 | +- [ ] HTML in `value` attributes is XML-escaped |
| 373 | + |
| 374 | +### Recommended |
| 375 | + |
| 376 | +- [ ] Shapes do not overlap unless intentional (use ≥40px gap) |
| 377 | +- [ ] Edge labels are short (≤4 words) |
| 378 | +- [ ] Layer cells have descriptive `value` names |
| 379 | +- [ ] All shapes fit within `pageWidth` × `pageHeight` bounds |
0 commit comments