All writing
6 min readEngineeringDesign

We did not build realtime co-editing, and here is the reasoning

Multiplayer cursors are the most demanded feature in this category and the one most often used by nobody. What we built instead, and when we would change our minds.

Nex does not have realtime collaborative editing. No coloured cursors, no two people typing in the same paragraph at once. This is a choice, not a gap in a roadmap, and it deserves a straight explanation rather than a “coming soon”.

What it actually costs

Concurrent editing is not a feature you add. It is a data model you adopt, and it reaches everything.

The document stops being a value you save and becomes a sequence of operations to be merged — a CRDT or an operational transform, either way a structure whose size grows with the editing history rather than with the content. Undo stops being a stack and becomes per-user undo over a shared timeline, which is a genuinely hard problem that most implementations get subtly wrong. Every custom block has to define what happens when two people change it at once. Offline edits need reconciliation. Version history has to be reconstructed from operations rather than read from a row.

And each of those decisions costs something the single-writer version gets for free — a document that is small, a save that either happened or did not, and a history you can read.

What most people actually do

The honest observation is that simultaneous typing in the same paragraph is rare. What is common is asynchronous collaboration: someone writes a draft, someone else reads it later and leaves remarks, the author responds and revises. The cursors are a demo; the comments are the work.

So we built the second thing properly. Comments anchor to a block, not a position, so they survive the edits made in response to them. They arrive in a sidebar you can read as a conversation or in the margin beside the paragraph. Mentions notify. Page history records what a session replaced so an unwanted edit is recoverable. That is the async loop, and it is closed.

What Nex does have

Everything except the document body is live. Rename a page and the sidebar updates everywhere immediately. Comment and it appears. Publish and the public page is current. Queries are subscriptions, so this is the default rather than something special.

The document body autosaves on a debounce and the last writer wins. If you and a colleague edit the same page in the same minute, one of you will overwrite the other, and page history will have what was replaced. That is a real limitation and we would rather write it down than let you find it.

When we would change our minds

If the common case turns out to be several people in one document at once, this reasoning is wrong and we will do the work. The way in is not closed off: block ids already exist and are stable, which is most of what a merge needs to identify what changed. Comments anchor to those ids rather than to positions, which is precisely the property that makes them survive a merge.

What we are not willing to do is adopt the whole cost of a distributed editing model on the assumption that it will be needed — and then find that the actual answer was that people wanted to leave each other notes.