CRDT sync with Yjs
Each document is a Yjs CRDT shared with every connected editor over a WebSocket. Edits are exchanged as small incremental updates, and the CRDT guarantees that all replicas converge to the same state regardless of the order updates arrive in — including edits made by two people in the same word at the same time. Because convergence is a property of the data type, brief disconnections are harmless: a client that drops offline keeps editing locally, resyncs its missed updates on reconnect, and merges cleanly with whatever happened while it was away. Undo is scoped per user: Cmd+Z reverts your own edits, never a collaborator’s.Presence
Everyone connected to a document sees:- Remote cursors and selections, colored per user and labeled with their name.
- Avatars of active collaborators in the document header.
One Durable Object per document
Every document is backed by its own Cloudflare Durable Object — a single-threaded authority that holds the live Y.Doc:- Sync and awareness run over hibernating WebSockets, so an idle document costs nothing while connections stay open.
- Access control is enforced at connect time and per message: users with viewer or commenter roles get a read-only connection that receives every update live but cannot write.
- The REST API goes through the same object.
PUT /api/docs/{id}/contentapplies its change to the live CRDT as a diff, so an API write shows up in every open editor instantly — and concurrent human edits merge with it instead of being overwritten. - Snapshots of the CRDT state and its serialized markdown are persisted, so a document survives eviction, hibernation, and deploys.