Yjs collaboration patterns
Yjs is a CRDT library that lets multiple clients edit the same document concurrently without conflicts. This recipe walks through the three patterns we use most when wiring Yjs into Meridian-backed apps: room provisioning, awareness presence, and persistence to durable storage.
1.Provision a shared room
Every collaboration session is scoped to a room name. Clients connecting to the same room name see each other's changes in real time. Use a stable identifier per document (slug, uuid, or composite key) so refreshes rejoin the same room.
import * as Y from 'yjs'
import { WebsocketProvider } from 'y-websocket'
const ydoc = new Y.Doc()
const provider = new WebsocketProvider(
'wss://collab.meridian.dev',
'doc-' + docId,
ydoc
)
const ytext = ydoc.getText('content')2.Broadcast awareness
Awareness state carries ephemeral data: cursor positions, user names, selection ranges, typing indicators. It is not persisted, so it is the right channel for presence UI without polluting the CRDT history.
Each peer sets its own awareness slice and subscribes to changes from others. Meridian's model: meridian/collab-summarizer can consume the awareness stream to produce live activity feeds.
3.Persist to durable storage
The WebSocket provider keeps clients in sync, but the room evaporates when the last peer disconnects. Snapshot the Y.Doc to durable storage (Postgres bytea, S3, or KV) on a debounced interval and rehydrate on the first connect. Use Y.encodeStateAsUpdate and Y.applyUpdate for round-tripping.