This episode covers real-time collaboration features: Operational Transformation, CRDT, cursor position distribution, version history, and libraries such as Yjs, ShareDB, and Automerge.

Two people type in the same document at the same time. If the server just applies "latest document wins", one person loses all their writing. Applications like Google Docs solve this with smart conflict algorithms.
Episode 20 covers real-time collaboration: how two clients edit one document without deleting each other. You will learn the two big approaches — Operational Transformation and CRDT — plus the libraries that already solve this problem so you do not have to write it from scratch.
Imagine a document containing "halo". Client A appends " dunia" at the end, client B appends " sayang" at the end — both based on the text "halo".
Versi bersama : "halo"
Edit A : "halo dunia"
Edit B : "halo sayang"If the server applies A then B, and B was computed against positions in "halo", the result is a mess. This is called a conflict: two operations valid on their own, but incompatible if simply applied.
The server needs a way to merge operations from many clients so the final result is consistent for everyone. That is where Operational Transformation and CRDT come in.
Operational Transformation shifts the position of an operation so it fits with other operations that arrived earlier.
const operasi = {
tipe: "insert",
posisi: 5,
teks: " dunia",
klien: "user-A",
urutan: 7,
};Every edit is represented as an operation: insert, delete, or retain at a specific position. When two operations overlap, a transform function adjusts the position of the later operation so both can be applied in any order.
function transform(a, b) {
if (b.tipe === "insert" && b.posisi <= a.posisi) {
return { ...a, posisi: a.posisi + b.teks.length };
}
if (b.tipe === "delete" && b.posisi < a.posisi) {
return { ...a, posisi: a.posisi - b.jumlah };
}
return a;
}transform(a, b) adjusts operation a's position against b, which was already applied. OT is proven reliable for text editors, but its implementation is complex — that is why most teams use mature libraries.
Conflict-free Replicated Data Types take a different approach: every change carries a unique identity, and all replicas reach the same result without a server deciding who wins.
const char = {
id: { klien: "user-A", counter: 42 },
teks: "x",
kiri: null,
kanan: null,
};Every character has a unique ID and a position relative to its neighbors. Because positions are relative, two clients can add characters at the same place without overwriting each other — both exist.
Besides the document content, you distribute the cursor position so other users see the cursor move in real time.
socket.on("cursor:move", (pos) => {
socket.to("doc:" + pos.docId).emit("cursor:moved", {
userId: socket.userId,
posisi: pos.posisi,
warna: socket.warna,
});
});cursor:move is broadcast only to collaborators of the same document, not to every connection. Cursor positions are ephemeral, so they do not need to be stored — just forwarded and continuously overwritten.
Collaborative documents keep a version history. CRDT makes undo easy because every operation has an identity; to roll back, you just emit the operation that cancels it.
Writing OT or CRDT from scratch takes months. Mature libraries have already solved this.
bun add yjs y-websocketYjs is the most popular CRDT with a ready-made WebSocket provider. ShareDB implements OT and fits if you need JSON documents database-style. Automerge focuses on offline-first mode with synchronization.
const Y = require("yjs");
const { WebSocketProvider } = require("y-websocket");
const doc = new Y.Doc();
const provider = new WebSocketProvider("wss://sync.example.com", "room-1", doc);
provider.on("sync", () => {
console.log("dokumen tersinkronisasi");
});WebSocketProvider(url, room, doc) connects the Yjs document to a y-websocket server. All edits, cursors, and awareness (who is currently viewing) are managed by the provider automatically.
Episode 20 opened the world of collaboration: from two conflicting edits overwriting each other, to a system that binds everyone to the same result. OT transforms operations to be compatible, CRDT makes all replicas converge, and ready-made libraries save you from the complexity.
Key takeaways:
In the next episode we build a real-time notifications system: notification architecture, user preferences, batching, and persistence of read and unread status.