#8

CodeSync — Collaborative Editor

January 12, 2026

RustNode.jsWebSocketsCRDTMonaco EditorReact

Real-time collaborative code editor (Google Docs, but for code). Multiple users with live cursor tracking. Rust handles document merging (CRDTs), Node.js manages WebSocket connections.

What is it?

A real-time collaborative code editor using Monaco Editor (VS Code's editor component). Multiple users edit the same document simultaneously with live cursors and automatic conflict resolution. The system is split into two microservices: a Node.js WebSocket gateway and a Rust CRDT engine.

Architecture

Browser connects via WebSocket to the Node.js gateway at wss://<host>/<SESSION_ID>. When a client sends a CRDT update binary, the gateway does two things simultaneously: (1) broadcasts it to every other client in the same session immediately, and (2) POSTs it to the Rust CRDT engine at /merge/<session_id>, which merges it into the persistent LoroDoc and returns a full snapshot.

If the Rust engine is unavailable (cold start), the gateway falls back to in-memory JS CRDT merge via the loro-crdt npm package. No data loss during engine restarts.

The CRDT: Loro

The CRDT library is Loro — a Rust-native library implementing a state-based CRDT for rich text. The Rust engine uses axum 0.8.8 as HTTP server and loro 1.10.3 for document state. Each session's LoroDoc lives in an LRU cache (up to 10,000 sessions).

Loro's text CRDT handles concurrent edits without coordination: each character has a unique ID (peer + counter pair). Concurrent insertions always produce a deterministic ordering. Deletions are tombstoned — the character's slot remains but is marked invisible. Two users deleting the same character converge to one deletion, not two.

Security layer

The gateway enforces an origin whitelist — connections from unknown origins are rejected. An internal auth token (X-Internal-Auth header) authenticates calls between the gateway and the Rust engine so the engine can't be hit directly.

IP rate limiting: 1000 requests/minute per IP. Exceed that: 10-minute block. Document size cap: 100KB per session.

Deployment on Cloud Run

Both services deploy to Google Cloud Run (project gemini-access-478409, us-central1).

Rust engine (codesync-crdt-engine): multi-stage Docker build — rust:1.87-bookworm for compilation, debian:bookworm-slim for the runtime image. 1Gi RAM, up to 5 instances.

Gateway (codesync-gateway): 512Mi RAM, up to 5 instances. Crucially, timeout set to 3600s — Cloud Run's default 300s timeout would terminate long-lived WebSocket connections. Frontend at colab-editor-live332.netlify.app.

Key takeaways

  • Loro CRDT: peer+counter character IDs, tombstone deletions, deterministic convergence
  • Gateway fallback pattern: JS CRDT as in-process backup when Rust engine is cold
  • Cloud Run WebSocket timeout: 3600s needed to keep long-lived connections alive
  • Multi-stage Rust Docker build: bookworm builder → bookworm-slim runtime for minimal image
  • LRU session cache in Rust: lru crate, bounding memory with max 10K sessions
Try it live →Watch on YouTube →← all projects