Build Google-Docs-style live collaboration with CRDTs
Two people open the same document and type at the same time. No spinner, no "someone else is editing", no lost paragraph. Build it yourself with Yjs: a shared document, a tiny sync server and two clients that make conflicting edits and land on exactly the same text. Then take one offline, edit it, reconnect, and watch it merge. You finish knowing why the hard version of this problem needs a CRDT, and why the obvious fix quietly eats people's work.
- An honest look at the cost (the metadata and tombstones a CRDT carries) and where to go next for production real-time infrastructure
- Comfort with the terminal and running commands. New to it? Do The terminal survival kit first.
- Node 18 or newer (this mission was built on Node 26). Check with
node --version. The Build your own API lesson is a good warm-up for the build-test-ship rhythm, though it uses Python; this one is all JavaScript. - A little JavaScript: functions, arrays and objects. You do not need to know Yjs, WebSockets or anything about distributed systems. Every file is complete and explained.
- A code editor. VS Code ↗ is free. A browser (any modern one) for the last step.
The problem: two people, one document
Before any code, get the problem clear. Two people editing the same thing at once is not a rare edge case, it is the normal case, and the naive answers all fail in ways you can name.
Picture a shared notes document. You and a colleague both have it open. You add a line at the top; at the same second, they add a line at the bottom. Nobody is waiting for the other. When the dust settles, you both want to see both lines, in the same order, on both screens. That is the whole job, and it is harder than it looks.
The first idea everyone reaches for is a lock: only one person may edit at a time, the way an old shared spreadsheet would say "read only, file in use". It works, and it is miserable. Collaboration stops being collaboration. Google Docs feels alive precisely because there is no lock.
The second idea is to let both edit and have whoever saves last win. We will build that in the next step and watch it delete someone's work in front of you.
The real answer is a CRDT (a Conflict-free Replicated Data Type): a data structure designed so that many copies can be edited independently, offline, in any order, and still merge back to the same value with no central referee. "Conflict-free" does not mean people never edit the same spot. It means the merge rule is defined for every case, so there is never a conflict the software cannot resolve on its own. That is the thing you are going to build on top of.
Set up the project. Make a folder, start a Node project, and install the three packages this mission uses:
Terminalmkdir crdt-demo cd crdt-demo npm init -y npm pkg set type=module npm install yjs@13.6.33 y-websocket@1.5.4 ws@8.22.0yjsis the CRDT library: it gives you shared data types (text, arrays, maps) that merge.y-websocketis a ready-made sync server and matching client.wsis the WebSocket library they run on.npm pkg set type=modulelets you useimportin.mjsfiles. The version pins matter here: Yjs clients and servers must speak the same update format, and mixing versions is the most common way this breaks (more on that in step 6).TipPrefer not to type every file? The starter kit has all of them, plus the browser page and a README. Unzip it, runnpm installinside, and every command below works.
node --version prints 18 or higher, and npm install finishes with a node_modules folder and yjs, y-websocket and ws listed in your package.json.If it breaks'npm' is not recognised + 2 more
'npm' is not recognised
'Cannot use import statement outside a module'
npm pkg set type=module, check package.json now contains "type": "module", and save your files with the .mjs extension as the lesson does.npm install is slow or fails behind a proxy
npm config set registry https://registry.npmjs.org/ and try again, or use the starter kit on a machine that can reach npm once, then copy the folder.