08
The URL is the account

CanVas

Realtime rooms pairing a live document with a live drawing canvas. No accounts, no passwords.

TypeScript realtime-collaborationcanvaswebsockets
click to turn
Two surfaces, one room

Live presence, simulated. Both surfaces are bound to the same Yjs document.

Landing — join by room name
running Landing — join by room name

Why two surfaces and not one

Text flows; canvas is spatial. Cramming both into one editor makes a bad version of each — you get sticky notes, or inline clip-art.

So CanVas keeps them as two purpose-built surfaces bound into one synchronised room: a BlockNote block editor and an Excalidraw infinite board, both writing into the same Yjs doc.

Sync topology
browser Anotes surface browser Bcanvas surface cloudflare workerpartyservery-partyserver durable objectone per room slugholds the Yjs docpersists to DO storagesurvives 0 clients BlockNoteblock editor Excalidrawinfinite board one doc

Each room slug is its own Durable Object, persisting the Yjs doc to DO storage — so a room survives with zero connected clients.

Realtime freehand canvas
running Realtime freehand canvas

The hard part

Different people can be on different surfaces at the same time and still see each other. That only works because presence lives on the shared document rather than on either editor.

Outcome

co-canvas

Chapter 09
Tessera

A pixel-art editor whose document is JSON a human can read and hand-edit — and an AI can rewrite.

continue
08 — CanVas
scroll · drag · ← →