CRDT rooms
CRDT rooms are Realtime rooms with document update and awareness helpers. Use them for collaborative editors, whiteboards, shared forms, kanban boards, canvas tools, and any feature where multiple clients edit the same state.
const document = live.crdtRoom("document_123")CRDT rooms also support the normal room methods such as join, presence,
members, history, snapshot, and restore.
Apply an update
Section titled “Apply an update”Send each document update with a client ID and optional clock:
app.post("/documents/:documentId/updates", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const body = await request.json() const document = live.crdtRoom(documentId)
return await document.applyUpdate({ update: body.update, clientId: body.clientId, clock: body.clock, })})update is JSON so you can store a compact operation, a patch envelope, or an
encoded update payload your client library understands.
Use Yjs updates
Section titled “Use Yjs updates”When your client uses Yjs, send the binary update as base64:
await live.crdtRoom("document_123").applyYjsUpdate({ updateBase64, clientId: "client_1", clock: 42,})Read missing updates with a state vector:
await live.crdtRoom("document_123").syncYjs({ stateVectorBase64,})See Yjs for the full flow.
Update awareness
Section titled “Update awareness”Awareness is live client state associated with a collaborative document:
app.post("/documents/:documentId/awareness", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const body = await request.json()
return await live.crdtRoom(documentId).awareness({ clientId: body.clientId, state: { cursor: body.cursor, selection: body.selection, color: body.color, }, })})Use awareness for cursors, selections, active tools, viewport ranges, and user display details.
Read the document stream
Section titled “Read the document stream”app.get("/documents/:documentId/state", async (request) => { const pathSegments = new URL(request.url).pathname.split("/") const documentId = pathSegments[2] const sinceClock = Number(new URL(request.url).searchParams.get("sinceClock") ?? 0)
return await live.crdtRoom(documentId).document({ sinceClock, limit: 200, })})The result contains ordered updates and current awareness state:
{ room: "document_123", kind: "room", updates: [ { updateId: "upd_123", update: { ops: [{ insert: "hello" }] }, clientId: "client_1", clock: 1, appliedAt: "2026-05-25T00:00:00.000Z" } ], awareness: [ { clientId: "client_1", state: { cursor: 5 }, updatedAt: "2026-05-25T00:00:00.000Z" } ]}Snapshot a collaborative document
Section titled “Snapshot a collaborative document”Use snapshots to create checkpoints:
const snapshot = await live.crdtRoom("document_123").snapshot()Snapshots include metadata, members, and recent messages. Store the returned
snapshotId when users need named versions or restore points.
await live.crdtRoom("document_123").restore(snapshot.snapshotId)