Agentic canvas SDK · Rust + WebAssembly · WebGL2
An infinite canvas SDK for the web, with one editor API that an agent calls and a person clicks. It runs headless — no browser, no DOM, no canvas element — so an agent can build and read a document on a server, and the same document opens in the UI. Underneath is a Rust and WebAssembly engine that writes GPU buffers straight into linear memory.
Recorded · five agents · 27 boxes, 26 arrows
Each of the five was given one band of the diagram, told to read the repository, and asked for boxes and arrows as JSON. What you are watching is what they returned, replayed call by call onto a real editor — the same createShapes a toolbar button calls.
Recorded, not live: the run is checked into this site so every visitor sees the same diagram and nobody pays a model per page view. The demo where a model really does answer is one click away.
Starting the WebAssembly engine…
Built for agents
Most canvases assume a person with a pointer. The parts an agent needs — a document that exists without a screen, an API that is the same one the UI uses, and output you can compare between two runs — tend to be the parts that were never designed for.
An agent calls the same `Editor` a toolbar button calls — `createShapes`, `select`, `rotateShapesBy`. There is no separate agent surface to keep in sync with the human one, and nothing an agent can do that a person cannot undo.
`createStore()` gives you a real document — pages, shapes, bindings, assets — with no browser, no canvas element and no window. An agent can build, read and validate a board on a server; the same document opens in the UI unchanged.
Index keys are jittered so two clients can insert in the same place without one of them being merged away — and jitter turns off under a test runner, so an agent's output is byte-comparable between runs. One switch, no configuration.
Records are checked against their type when they enter the store, so a malformed shape from a model throws at `put` rather than mounting and rendering. Props the build has never heard of are kept, so a round trip loses nothing.
Benchmark · median ms · lower is better
Median milliseconds against tldraw 5.4, lower is better. mocanvas builds a scene about 2.6× faster at every size, and the interaction gap widens as the scene grows — from 1.8× at a thousand shapes to 2.3× at twenty thousand.
Faster to build a scene
20,000 shapes, against tldraw 5.4
Faster to drag a selection
20,000 shapes, against tldraw 5.4
To create 20,000 shapes
tldraw 5.4 takes 387 ms
Creating shapes · mocanvas · tldraw 5.4 · ratio
1,000 shapes
5,000 shapes
20,000 shapes
Dragging a selection · mocanvas · tldraw 5.4 · ratio
1,000 shapes
5,000 shapes
20,000 shapes
Measured on an Apple M3 Pro, headless Chromium on the Metal backend, default settings on both sides. Two things count against us and are worth knowing: every shape here uses the hand-drawn stroke, which is our most expensive path, and pan and zoom is left out because mocanvas sits at the harness’s own frame floor in every case — we cannot measure it, so we do not claim it. It is our own benchmark of our own library; the method and the rest of the caveats are in the docs.
Coming from tldraw
The editor API is shaped after tldraw’s, because we think they got that design right — we built products on it before we built this. @mocanvas/compat gives you the TL-prefixed names and a stylesheet that maps tldraw’s CSS custom properties onto ours, so a migration starts as two import changes rather than a rewrite.
It is not a fork and shares no code: mocanvas was built without reading tldraw’s source, from its public documentation and sample files. So the coverage is a measured number rather than a promise, and the guides say plainly which parts are missing.
mocanvas is built by Symbio. Free for non-commercial, non-profit and development use; commercial use needs an agreement. Not affiliated with or endorsed by tldraw.