Skip to content
All projects
SystemsFeb 2026Live

Synapse: An End-to-End-Encrypted Multiplayer Canvas

An End-to-End-Encrypted Multiplayer Canvas

A local-first thinking canvas that works fully offline, merges edits without conflicts using CRDTs, and is end-to-end encrypted so the relay server cannot read your data. A time slider replays the whole document, keystroke by keystroke.

synapse-charan.vercel.app/about-project
Synapse, the live site
Year
Feb 2026
Timeline
9 weeks
Type
Systems
Status
Live

~230 lines

The relay server is about 230 lines and only stores and forwards ciphertext, logging each update as an opaque byte count. The room key stays in the URL fragment and never reaches it.

01

Overview

Synapse is a real-time collaborative canvas built on three decisions: the client holds the document (a Yjs CRDT), the server only relays ciphertext, and history is the update log replayed. Open it in two windows, take one offline, keep editing in both, then reconnect, and the documents merge with no conflicts. Drag the time slider and the whole board rewinds and replays.

02

The hard parts

  1. 01

    Origin tracking: applying a remote CRDT update also fires the local "update" event, so a naive relay re-sends it and the room turns into a broadcast storm. That bug took three days to find.

  2. 02

    Offline durability: close the tab, lose Wi-Fi, keep editing, and have everything merge cleanly on reconnect.

  3. 03

    Keeping the server unable to read anything while still letting late joiners catch up on full history.

  4. 04

    Remote cursors arrive at packet rate and look broken if you render each raw position.

03

The approach

Each client keeps the document in a Yjs CRDT persisted to IndexedDB. A custom EncryptedProvider seals every update with AES-256-GCM before it leaves the device and sends ciphertext to a relay of about 230 lines that knows nothing about canvases. The broadcast-storm fix is two lines: tag every applied network update with the provider as its transaction origin, and return early in the local handler when the origin is your own. Cursors are interpolated outside React and written straight to the DOM, so presence looks smooth. Time travel needs no extra storage: the ordered CRDT update log is the history, so replaying updates[0..t] into a throwaway doc reconstructs any past state.

04

Outcome

With two windows open and one in airplane mode, edits made in both merge without conflicts on reconnect, and a scrubber rewinds and replays the board. A headless smoke test speaks the same encrypted wire protocol and asserts that both clients converge and that a late joiner can reconstruct history, so a convergence regression fails the test.

05

What I'd do differently

End-to-end encryption here means the relay can't read your canvas. It does not protect against anyone you share the link with (the key is in the link) or against traffic-analysis metadata, and I would rather state that limit than over-claim. Next: per-room key rotation, a WebRTC peer-to-peer transport with a relay/P2P toggle, and a per-character text CRDT for concurrent editing inside a single node.

06

Stack

crdt
Yjsy-indexeddb
crypto
WebCryptoAES-256-GCM
transport
custom blind WebSocket relay (Node)
frontend
Next.js (App Router)TypeScript (strict)custom SVG/DOM canvas

Like what you see?

Let's build the next one.

Hiring, or have a problem that needs this kind of engineering? I read every message myself.