Collaborative Editor

Real-time collaborative text editor using operational transforms and WebSockets.

Aug 2023

Tech Stack

Node.jsWebSocketCRDTY.jsMonaco EditorRedis

Overview

Like Google Docs but for code. Multiple people editing the same file in real-time, with syntax highlighting and no conflicts. Built this for a hackathon project where we needed to pair program remotely and hated VS Code Live Share's latency. Uses CRDTs (specifically Y.js) instead of operational transforms because CRDTs are way easier to reason about and don't require a central server to resolve conflicts.

Technical Details

  • Monaco Editor (the thing VS Code uses) for the editor UI - syntax highlighting, autocomplete, all built-in
  • Y.js for CRDT-based conflict-free editing - it's magical how well it works
  • WebSocket server in Node.js broadcasting Y.js update messages between clients
  • Redis pub/sub for syncing across multiple WebSocket server instances
  • Presence awareness showing who's online and where their cursor is (different color per person)
  • Y.js syncs to PostgreSQL for persistence every 30 seconds and on disconnect
  • Client reconnection logic that replays missed updates from the server
  • Document forking - you can branch off to try something without affecting others

Challenges

  • Cursor positions in CRDTs are hard - text indices shift as people type. Had to use Y.js relative positions which are stable across edits.
  • Scaling WebSockets across multiple servers is annoying. Redis pub/sub works but adds latency. Considering switching to a proper message broker.
  • Large documents (>10K lines) start to lag because Y.js stores the entire history. Working on garbage collection for old edits that nobody will undo.
  • People typing very fast can flood the WebSocket with updates. Added debouncing and batching, improved it a lot.

Results

  • My friend group uses it for coding sessions - 8 active users
  • Successfully edited a 2000-line file with 4 people simultaneously without conflicts
  • Average latency for seeing someone else's edits: 120ms on good connections
  • Had one bug where two people's changes got lost - turned out I wasn't handling disconnections correctly. Fixed now.