Skip to content

Blog & content

Blog article layout

Readable long-form article template with back link, title, lede, author bar with actions, diagram header, prose, quote, code and tags.

All posts

Engineering · 9 min read

Designing an offline-first sync engine for a collaborative editor

What we learned replacing our REST save button with CRDTs, and why conflict resolution turned out to be the easy part.

LF

Lena Fischer

For three years our editor saved documents the way most web apps do: debounce keystrokes, send the whole document to the server and hope nobody else edited it in the meantime. It worked until our customers started working on planes.

Why we picked CRDTs

Operational transforms need a central server to order every change. CRDTs let each client merge changes independently, which is exactly what you want when the network is unreliable.

The hard part was never merging text. It was deciding what “the latest version” means to a human.
const doc = new Y.Doc();
const text = doc.getText("body");
provider.on("sync", () => console.log("synced"));
  • Persist updates to IndexedDB before acknowledging a keystroke.
  • Compact the update log nightly so cold loads stay under 200 ms.
  • Show presence cursors only after the first successful sync.

Stack: React + Tailwind CSS + lucide-react icons

Interactive: no (works as a server component)

Licence: free to use in any project

More blog & content components