Home · Docs · Sharing · Real-time collaboration

Real-time collaboration

Multiple editors in the same doc see each other's cursors and edits live. Built on Yjs CRDT, broadcast through Supabase Realtime. No conflicts, no save-the-merge dialog.

When more than one person is editing a document, you see each other in real time: colored cursors with name labels, selections that move as the other person highlights, and a small stack of presence avatars in the toolbar. Edits merge automatically — there’s no save-the-merge dialog, no overwriting each other’s work.

kyoto-trip LS+1 Editing

Kyoto, days 1-3

We land in Kyoto on the 12th and have three full days before Osaka. The bamboo grove at LeeArashiyama is best at dawn, Fushimi Inari takes a morning,Sam and the Nishiki food markets are worth a slow afternoon.

How it works

Each document has a Yjs CRDT session — Y.Doc for the content, Awareness for cursor positions and selections. Both ride over a per-document Supabase Realtime channel:

Yjs guarantees that all clients converge on the same content regardless of the order updates arrive — this is the formal CRDT property. Two people typing into the same paragraph at the same time both land, with a deterministic merge.

Who counts as a collaborator

Anyone with Write or Manage access on the doc — added via Invite by email or folder sharing cascade. Public link viewers don’t collaborate because:

The presence stack only shows signed-in users with Write access who currently have the doc open in Edit mode.

Cursors

Each peer’s cursor renders as a vertical color bar at their selection start with a small name tag above it. The Tiptap CollaborationCaret extension handles the rendering.

AspectBehavior
ColorStable per user — derived from a hash of their user ID so the same person gets the same color across sessions
NameTheir display name from profiles (or “Anonymous” if blank)
SelectionWhen someone has text selected, the same color tints the selection background lightly on your screen
IdleCursors stop updating when the other person hasn’t moved in a while, but stay visible at their last position
DepartureWhen someone leaves (closes the tab, navigates away), their cursor disappears within a couple of seconds

The presence stack

In the doc toolbar (top-right area), a small overlapping stack of circular avatars shows who else is currently in the doc:

ElementDetails
Avatar circleThe peer’s profile picture (or initials on a colored background matching their cursor)
Up to 4 visibleBeyond that, a “+N” overflow chip appears
HoverTooltip shows the person’s display name
DeduplicationThe same person in two tabs counts once
YouYour own presence isn’t in the stack — only others

The stack updates instantly as people join and leave.

Saving in a collab session

When multiple people are editing, every save flushes the full Y.Doc state to documents.yjs_state alongside the content text. This means:

Offline collaboration

Yjs is a local-first CRDT — if you lose your network mid-edit:

This is the killer property — no merge UI, no conflict resolution, no “you have lost your changes” prompt.

Limits and edge cases

AspectDetail
Concurrent editors per docPractical: tens of editors. Yjs scales well; the bottleneck is usually screen-share of who’s where, not the CRDT.
LatencyEdits typically arrive within ~150 ms on a healthy connection
Doc sizeYjs encodes incrementally; the persisted yjs_state grows with edit history. Periodic compaction is on the roadmap.
CommentsHave their own timeline and don’t live in the Y.Doc; they sync via Postgres realtime separately
Image uploadsDon’t go through Yjs — they upload to R2, then the image node (with its URL) is inserted into the doc, which then syncs via Yjs

What “Write access” actually grants

Real-time collaboration is unlocked by Write or Manage on the document — see Permissions for the full level grid. Read-only collaborators can comment but cannot type into the body.