CRDTs are hard
Table of contents
YJS §
YJS has the greatest community and contributor support. It’s also one of the oldest implementations. It’s also lightweight, at ~26Kb. Most people stop here.
Pros:
- Lightweight
- Battle-tested
- XML types map nicely to HTML
Cons:
- Code is a mess
- All
export *
, so no tree-shaking
- All
- Single maintainer
- Serialized documents lose undo history, so users won’t be able to revert to previous translation versions
Automerge §
Automerge offers a very convenient JS-first API. It maps the JS shapes you give it to reasonable CRDT types.
Pros:
- Convenient API
- Plug and play network and storage
- Run by inkandswitch, a good local-first research and publisher
- Excellent rich text schemas
Cons:
- Core package is heavyweight ~931Kb
- Requires WASM
- Poor performance
Loro §
Loro is a fairly new Eg-walker implementation with rich text.
Pros:
Cons:
- Core package is heavyweight ~991Kb
- Requires WASM
Collabs §
Collabs allows strongly-typed primitives with custom merge strategies.
Pros:
- Customizable
- Small ~27Kb
Cons:
- Must customize with complications
- Main developer graduated college and moved on from project
CRDTs are hard §
Ugh, none of these implementations support preserving merge history AND linking between documents AND have a reasonable bundle size. Guess it’s time to make my own! I only really need rich text.
Let’s look at plain-text merging first. FugueMax is the best algorithm and has a few variants. But it’s pretty complicated. Then for preserving history we need to save a log of operations. To identify merge conflicts we need to give those operations identifiers and store them in some kind of causal graph. Finally we can use FugueMax, but we do have to temporarily “undo” and “redo” nodes as we walk the tree.
Oh, and for any of these to perform reasonably you’ll need to encode runs to save on memory.
I just described Eg-walker, and it’s not simple at all. I’ve implemented it a couple times, and it requires complex graph types to perform well.
Conclusion §
I don’t think I’ll be using CRDTs for anything besides live shared editing. I’ll stick to traditional source control algorithms for user annotations.