Architecture diagrams from a JSON spec

You write what exists and what talks to what. excalix does the layout, the shapes and colours, the text measurement and the arrow bindings, and draws it in Excalidraw's hand-drawn style as an .excalidraw file, an SVG and a PNG.

Hand-drawn architecture diagram titled order pipeline. A Web app sends POST /orders to the Order API, which sits with a Fulfilment service in an EKS group, inside an AWS eu-north-1 group. The Order API writes to Postgres, talks both ways with Redis, and publishes to the orders.created queue with a dashed arrow. The queue feeds Fulfilment, which calls Stripe, drawn as a dashed external box, with the label charge.
Every shape, colour and route above came from the spec below, which says nothing about where anything goes. Open the SVG at full size.

The spec behind it

order-pipeline.json
{
  "title": "order pipeline",
  "direction": "lr",
  "groups": [
    { "id": "aws", "label": "AWS eu-north-1" },
    { "id": "k8s", "label": "EKS", "parent": "aws" }
  ],
  "nodes": [
    { "id": "web", "label": "Web app", "kind": "client" },
    { "id": "api", "label": "Order API", "kind": "service", "group": "k8s" },
    { "id": "worker", "label": "Fulfilment", "kind": "service", "group": "k8s" },
    { "id": "q", "label": "orders.created", "kind": "queue", "group": "aws" },
    { "id": "pg", "label": "Postgres", "kind": "datastore", "group": "aws" },
    { "id": "redis", "label": "Redis", "kind": "cache", "group": "aws" },
    { "id": "stripe", "label": "Stripe", "kind": "external" }
  ],
  "edges": [
    { "from": "web", "to": "api", "label": "POST /orders" },
    { "from": "api", "to": "pg" },
    { "from": "api", "to": "redis", "arrows": "both" },
    { "from": "api", "to": "q", "style": "async" },
    { "from": "q", "to": "worker", "style": "async" },
    { "from": "worker", "to": "stripe", "label": "charge" }
  ]
}

Install in two lines

Node 22 or newer. Text measurement and export run in headless Chromium, which is a separate download, so that comes first.

Terminal
npx -y playwright@1.63.0 install chromium
npx -y excalix render spec.json -o out/spec

That writes out/spec.excalidraw, out/spec.svg and out/spec.png. The getting started guide covers validation, the JSON Schema and connecting an agent.

A kind fixes each node's shape and colour; "style": "async" is what draws the two dashed arrows. The spec reference lists every field.

What you can rely on

Text fits its box
Labels are measured with the real Excalifont in headless Chromium, and each box is sized around the text it holds.
The same spec gives the same bytes
Output is identical from run to run and between macOS and Linux. CJK and emoji labels are the known exception, tracked in issue #5.
It opens on excalidraw.com unchanged
Labels stay attached to their boxes and arrows stay bound to their ends, so the file is yours to keep editing by hand.
Every problem in one pass
Validation names each path, what arrived and what would have been valid, with a "did you mean" when an id is close to one that exists.
Nothing visual to configure
There are no colours, sizes or positions in the spec. Two diagrams made a year apart look like one set, and a change to the spec shows up as a reviewable diff.
The agent sees what it drew
The MCP tool returns the PNG inline in the same result, so an agent can look at the picture and call again with a better spec.

An Excalidraw MCP server for your agent

An .excalidraw file is nothing but coordinates, and an agent asked to draw one has to invent all of them. With excalix registered, the agent writes the topology instead and calls one tool, sketch, which writes the three files and returns the PNG in the same turn. In Claude Code that is one command:

Terminal
claude mcp add excalix --scope user -- npx -y excalix mcp

Cursor, VS Code, Claude Desktop and other MCP clients take the usual mcpServers entry, shown in getting started. What the tool accepts and returns, field by field, is on the MCP server page.

Where to go next