Triamorph Systems

← Engineering Dispatches / Full-Stack

Real-Time Collaborative Canvas and Document Architecture: Integrating React, TipTap, and Yjs CRDTs over WebSockets

By Hammad Haider · 13 min read read

Building multiplayer collaborative applications (like Notion, Figma, or Google Docs) is one of the pinnacle challenges of full-stack engineering. Traditional database locking mechanisms fail because users cannot wait for server round-trips while typing at 80 words per minute. By pairing Yjs Conflict-Free Replicated Data Types (CRDTs) with TipTap (ProseMirror) and distributed WebSocket servers, documents synchronize peer-to-peer and across server clusters with mathematically guaranteed convergence.

Architectural Takeaways

  • CRDTs (such as Yjs) resolve concurrent character insertions and deletions locally without requiring a central server to arbitrate lock order, making offline editing seamless.
  • Use the Yjs Awareness protocol to broadcast ephemeral presence data (multiplayer cursor positions, selections, and user avatar badges) without cluttering document storage.
  • Deploy Hocuspocus or custom Bun WebSocket servers backed by Redis Pub/Sub to scale real-time collaboration across multiple load-balanced container instances.

1. Operational Transformation (OT) vs CRDTs

Operational Transformation (OT), famously used in early Google Docs, requires a central server to sequence and transform concurrent editing operations. If the client loses connection, reconciling divergence is mathematically complex.

Conflict-Free Replicated Data Types (CRDTs) structure document characters into unique Lamport timestamps. Whether operations arrive in order or out of order, applying commutative operations guarantees identical document states across all clients.

2. Connecting TipTap & React with Yjs Document State

TipTap provides a headless ProseMirror interface. Through the `y-prosemirror` binding, every keystroke mutates a `Y.XmlFragment`, broadcasting delta updates via WebSocket.

3. Real-Time Multiplayer Cursors & Selection Awareness

The Awareness protocol sends lightweight JSON payloads containing user names, colors, and cursor anchor indices. When a remote collaborator selects a paragraph, the UI renders their cursor name tag in real-time with CSS transitions.

4. Scaling Distributed WebSocket Servers with Redis Pub/Sub

To scale beyond a single Node.js instance, Hocuspocus WebSocket servers are clustered via Redis Pub/Sub extension. When Node A receives a keystroke from Client 1, it broadcasts the binary update to Redis, propagating changes to Client 2 connected to Node B.

Read more technical guides on our Dispatches Index →