Rust · WebAssembly · CRDT

kilim

Three people edit the same text over a slow, lossy, out-of-order network — and still end up with exactly the same document. No server, no locks, no merge conflicts.

The network

converged

0 messages in flight · 0 delivered · 0 duplicates

Inside the CRDT

Every character has a unique id site:seq and a Lamport clock. Deleted characters stay as tombstones so late-arriving edits can still find where they belong.

Real sync across browser tabs

Open this page in a second tab and type below. Tabs sync through BroadcastChannel; a newly opened tab sends its version vector and receives only the operations it is missing. The document is also saved locally, so it survives a reload.

This tab is site · version {}

How it works

  1. Every insert remembers its left neighbour (its origin) instead of an index — indices change, ids don't.
  2. Concurrent inserts after the same origin are ordered by (lamport, site), newest first. Every replica runs the same rule, so every replica picks the same order.
  3. Deletes leave tombstones, so an insert that arrives late can still attach to a deleted neighbour.
  4. Operations are idempotent (duplicates are ignored) and buffered until their dependency arrives, so delivery order does not matter.
  5. Version vectors let a replica that was offline ask for exactly the operations it missed.
import init, { Doc } from "@ardazeybek-dev/kilim";
await init();
const doc = new Doc(siteId);
const ops = doc.insert(0, "merhaba");   // broadcast these
other.applyRemote(ops);                  // any order, any number of times