Triamorph Systems

← Engineering Dispatches / Full-Stack

Real-Time Collaborative Canvas: Architecting Figma-Grade Multi-User Software with WebSockets & Yjs

By Hammad Haider · 13 min read read

Building multi-user collaborative tools like Figma or Miro requires solving distributed concurrency, spatial rendering, and latency compensation simultaneously. Naive client-server architectures fail when two users move the same element simultaneously or when a temporary network hiccup overwrites off-screen shapes. This architectural dispatch explains how to build production multi-user canvas applications using Yjs CRDTs and WebSockets.

Architectural Takeaways

  • CRDTs (Conflict-Free Replicated Data Types) enable concurrent, offline-resilient document edits that mathematically converge to the same state across all peers.
  • Separate ephemeral presence state (live user cursors, viewport bounding boxes) from persistent document state to prevent database bloat.
  • Use R-tree spatial indexes (rbush) to render only shapes visible in the user’s immediate viewport, keeping 60 FPS performance across 50,000+ objects.

1. Why CRDTs Beat Operational Transformation (OT)

Operational Transformation (OT) requires a single authoritative server to order and transform operations sequentially. Under network disconnection or high packet latency, OT stalls. CRDTs ensure that any operation can be applied locally immediately and synced out-of-order, always resolving to deterministic convergence.

2. Modeling Canvas Elements with Y.Doc and Y.Map

Here is the core setup connecting a local HTML5 canvas state to a Yjs shared map and WebSocket provider.

3. Spatial Viewport Culling & 60 FPS Rendering

In large canvases containing 10,000+ geometric paths, executing canvas draw calls for off-screen items drops frame rates below 20 FPS. By inserting all shapes into an R-tree index, the engine queries bounding boxes intersecting the active camera viewport in sub-millisecond time.

4. Ephemeral Presence & Live Multiplayer Cursors

Transmitting cursor mouse coordinates at 60 Hz floods network sockets. We sample mouse positions at 20-30 Hz, broadcasting over Yjs awareness protocols, and use quadratic Catmull-Rom spline interpolation on client displays for fluid 60 FPS cursor motion.

Read more technical guides on our Dispatches Index →