
To build a real-time collaborative editor in 2026, pick a CRDT library (Yjs or Automerge) for conflict-free sync, pair it with a rich-text framework (Tiptap or ProseMirror), and pipe updates through a WebSocket server (Hocuspocus, or a hosted layer like Liveblocks). Add presence, cursors, and comments on top. Skip Operational Transform unless you are forking Google Docs.
Most teams underestimate two things: offline-first behavior, and the long tail of UX work (cursor jitter, selection sync, comment threads, undo across users). The library choice takes a day. The UX takes a quarter.
Collaborative editing stopped being a novelty around 2022. Figma, Notion, Linear, Pitch, and Coda made multiplayer feel like the default. Customers now expect a cursor with someone's name on it inside any tool that holds shared state.
The shift in 2026 is that you no longer have to build the sync layer yourself. Yjs hit production scale at companies like Notion and Linear. Liveblocks turned the whole stack into a hosted SDK. Convex and Supabase added realtime primitives that cover 80% of presence and broadcast use cases. The bar for "minimum viable multiplayer" dropped from six months to a weekend.
The flip side: the bar for good multiplayer went up. If your competitor ships smooth cursors and instant comments, your janky 200ms sync will lose deals.
Every real-time editor sits on one of three foundations. Pick the wrong one and you will rewrite the sync layer inside a year.
| Approach | How it works | Best for | Trade-offs |
|---|---|---|---|
| CRDT (Yjs, Automerge) | Each client holds a replica. Edits merge deterministically without a central server. | Offline-first apps, peer-to-peer, anything Notion-shaped | Larger document size, eventual consistency, harder to do schema migrations |
| OT (ShareDB, what Google Docs uses) | Edits are transformed against concurrent edits by a central server. | Linear edit history, server-authoritative apps, plain-text docs | Server is single point of failure, custom transform functions per data type, painful to extend |
| Hosted (Liveblocks, Convex, Supabase Realtime) | Someone else runs the sync server. You get an SDK. | Teams that want multiplayer in two weeks, not two quarters | Vendor lock-in, monthly cost scales with MAU, less control over conflict resolution |
The honest take: in 2026, CRDTs win for most new editors. They handle offline gracefully, they scale horizontally (any node can take a write), and the ecosystem around Yjs in particular is mature. OT is still the right choice if you need a strict server-authoritative history (legal docs, anything regulated), or if your edit operations don't fit cleanly into a CRDT data model.
Hosted services are the right choice when your team is small, your runway is short, and your differentiation is somewhere other than the sync engine.
Here is what the field looks like as of mid-2026.
The default choice. Powers Notion's collaborative blocks, Linear's comment editor, Evernote's new editor, and dozens of YC-funded tools. Document size scales linearly with edit count, but the y-indexeddb provider gives you free offline storage and a y-protocols package handles awareness (presence, cursors) cleanly. Pair with y-websocket or Hocuspocus for the server.
The footgun: Yjs documents grow forever unless you snapshot. Plan for a daily compaction job on docs older than 30 days.
Maintained by Ink & Switch. Stronger theoretical foundation than Yjs (Automerge 2.0 is a port of the original research that defined the JSON CRDT). Better Rust core, smaller bundle in some benchmarks. The trade-off: smaller ecosystem, fewer rich-text bindings out of the box. Good fit if you need local-first across platforms (it has solid Swift and Kotlin bindings).
Built on top of Yjs under the hood, but you never touch the protocol. You get presence, comments, threads, notifications, and storage as React hooks. Pricing in 2026 starts free up to 50 MAU, then ~$29/mo for a Starter tier, with $299/mo and up for production teams. The Pro tier covers most pre-Series-B SaaS.
Liveblocks is the right pick if you want to ship multiplayer this sprint, not this quarter. The lock-in is real but the SDK quality is excellent.
Not a CRDT. Convex is a transactional database with realtime subscriptions baked in. Great for collaborative apps where the state is more "shared object" than "rich document" (Linear-style issues, Notion-style databases, kanban boards). For a true rich-text editor, you would still use Yjs on top of Convex's storage.
Cheapest path if you already use Supabase. It gives you presence and broadcast channels for free, plus row-level subscriptions. Not a sync engine for rich text on its own, but a great transport layer if you want to ship your own CRDT updates over it.
The OT veteran. Still actively maintained. Used by the original Etherpad-lite community and a few enterprise tools. Pick it only if you have a hard requirement for server-authoritative edit history.
For most teams starting fresh in 2026, the stack that ships fastest with the fewest regrets is:
If you want zero-ops and you are pre-revenue, swap Hocuspocus for Liveblocks. Same Yjs underneath, but they run the server, handle scaling, and ship a polished comments and presence SDK. You can always migrate off later (the Yjs document format is identical).
For non-rich-text use cases (kanban boards, dashboards, multi-cursor design tools), reach for Convex or Liveblocks Storage instead. You will write less glue code.
Once the stack is chosen, the actual work breaks into six tracks. Each one has its own quarter-of-pain if you ignore it.
Decide what a "document" is in your app before you write a line of sync code. With Yjs, you have Y.Map, Y.Array, Y.Text, and Y.XmlFragment as your building blocks. Rich text uses Y.XmlFragment (Tiptap and ProseMirror plug straight in). Structured data uses Y.Map.
Mistake to avoid: storing serialized JSON in a Y.Text. You lose all merge benefits and end up with last-write-wins.
Run a WebSocket server (Hocuspocus is the easy answer). Persist documents to Postgres or Redis between connections. Hocuspocus has an onStoreDocument hook for this; debounce writes (every 2 to 5 seconds is typical) so you do not hammer your DB on every keystroke.
For offline support, y-indexeddb mirrors the document locally and syncs on reconnect automatically. This is the single biggest UX win and it costs you one import line.
Yjs ships y-protocols/awareness for ephemeral state (cursor positions, selection ranges, user names, colors). Awareness state is not persisted, which is exactly what you want. Cursors should jitter-smooth on the client (a 100ms ease is enough) so they do not feel laggy.
Practical detail: cursor positions need to survive concurrent edits from other users. ProseMirror has helpers for this. Tiptap exposes them via the Collaboration and CollaborationCursor extensions.
CRDTs handle the technical merge for you. They do not handle the semantic merge. If two users edit the same paragraph and one deletes it while the other adds a sentence, the deletion wins (the sentence is gone forever). Decide upfront whether your app needs explicit conflict UI (Google Docs-style suggestions) or whether last-write-wins is acceptable.
For most product tools, the latter is fine. For legal or financial docs, build a suggestion mode and require explicit accept/reject.
This is where teams underestimate the scope. Comments need to anchor to a position in the document that survives edits around it. ProseMirror has Decoration and Mark for this. Tiptap Pro ships a Comments extension. Liveblocks ships Comments and Threads as a first-class feature.
The hard part: an anchored comment whose source text gets deleted. Decide whether the comment "orphans" (still shows but flagged as outdated) or disappears. Most users prefer orphan-with-flag.
Documents need ACLs. The WebSocket server has to verify a token on connect and authorize each document subscription. Hocuspocus has an onAuthenticate hook. With Liveblocks, you implement an auth endpoint that mints room tokens.
A common bug: assuming the auth check at connect time is enough. Re-check on document open, because permissions can change mid-session. If you are also gating sensitive data behind realtime channels, the patterns in our note on server-sent events vs WebSockets are worth a read before you commit to a transport.
Five mistakes we see in collaborative editor postmortems, almost every time:
y-protocols/sync with batching, or rate-limit at the server.Y.UndoManager is per-client by default, which is what you want. But you have to tell it which transactions to track (only the current user's, not collaborators'). Get this wrong and undo deletes your collaborator's work.If you want a pre-launch sanity check on choices like the ones above, our tools/ship-or-skip grader will audit your stack against what actually ships in 2026.
Two cases where you should not build a collaborative editor at all.
You have fewer than 100 active users. Multiplayer adds 6 to 12 weeks of engineering work plus ongoing operational complexity (WebSocket servers, sticky sessions, document storage, presence debugging). For a tool with 50 users, a "refresh to see changes" pattern is fine, and you can revisit the decision when retention proves out.
Your data is not shared in real time. If users edit their own documents and occasionally share read-only links, you do not need CRDTs. Save the document on blur, render the share view server-side, done. This is the right pattern for most blog editors, form builders, and per-user dashboards. The same principle applies to most internal tooling, where the patterns in our guide on how to write production-grade tests in 2026 matter more than your sync engine.
A senior engineer ($1,500/week on Cadence) can stand up the Yjs + Tiptap + Hocuspocus stack with presence, cursors, and a basic comment thread in 1 to 2 weeks. Comments, anchoring, and offline support add another 2 to 3 weeks. A lead ($2,000/week) is the right call if you need to architect for 10k+ concurrent rooms or design custom conflict resolution.
Every engineer on Cadence is AI-native by default, vetted on Cursor / Claude Code / Copilot fluency before they unlock bookings. For a CRDT integration where the docs are dense and the failure modes are subtle, that vetting matters: the median time-to-first-commit on our marketplace is 27 hours, but the actual differentiator is how fast they pattern-match on Yjs internals when the inevitable awareness bug shows up.
If you would rather not run the sync server yourself, start with Liveblocks for the first 90 days, then graduate to self-hosted Yjs + Hocuspocus once you cross 5,000 MAU. The Yjs document format is identical between the two; the migration is real but bounded.
Building multiplayer this quarter? Book a senior engineer on Cadence ($1,500/week, 48-hour free trial) who has shipped Yjs to production. Replace any week, no notice period.
A basic Yjs + Tiptap editor with presence and cursors takes a senior engineer 1 to 2 weeks. Full feature parity with Notion-level collaboration (comments, threads, offline sync, mobile) is a 3 to 6 month project for a small team. Hosted SDKs like Liveblocks cut the initial timeline in half.
Use CRDTs (Yjs or Automerge) for new editors in 2026. They handle offline gracefully, scale horizontally, and have a healthier open-source ecosystem. OT is still the right call only for strict server-authoritative apps (legal, regulated finance) or when you need linear edit history for compliance.
Liveblocks is free up to 50 MAU, $29/mo at the Starter tier, and $299/mo and up for production teams. Self-hosting Yjs costs you a small VPS for Hocuspocus plus Postgres for storage ($20 to $100/mo at small scale) and 1 to 2 weeks of engineering setup. Liveblocks wins on time-to-launch; self-hosting wins on cost at scale.
Yes, if the editor uses ProseMirror, Slate, CodeMirror 6, or Lexical. Tiptap (ProseMirror) has the best Yjs bindings. Slate has community bindings. CodeMirror has y-codemirror.next. If you built a custom editor on contenteditable, retrofitting CRDTs is harder than rewriting on a framework.
Use y-indexeddb to mirror the Yjs document to the browser's IndexedDB. The library handles sync on reconnect automatically: it merges local edits with server state using the CRDT, with no conflict prompts needed. For longer offline sessions (days), add a "last synced" UI indicator so users know their work is not yet shared.
Backend developer at withRemote. Writes on API design, observability, and database trade-offs.