Why we're moving away from Yjs
Why not YJS.
1 - Editing conflict resolution
https://www.moment.dev/blog/lies-i-was-told-pt-1 https://www.moment.dev/blog/lies-i-was-told-pt-2
2 - Don’t need p2p
Professional document editor with organizational clients p2p is not the goal
3 - ProseMirror transaction steps from other clients cover the entire document
https://github.com/yjs/y-prosemirror/issues/113 This causes all sorts of issues. From filtering certain steps to only include steps on certain nodes, to decorations blipping as soon as another client makes a change. This is terrible when relying on decorations for things like proofreading.
4 - Quirks
https://github.com/yjs/y-prosemirror/issues/202 Imagine editing a footnote. Naively we left the selection on the footnote anchor, being an inline atom. This caused a crash of the editor and no way for other clients to delete the footnote.
5 - Undo is painfully slow
Undo redraws the entire document. On a 200 pages document, an undo can take more than a second to complete.
6 - Marks on nodes are not persisted through yjs
This was annoying. Some nodes like list numbers should have marks. But they can’t. So we had to add a special plugin to persist the marks on the nodes by converting them to attributes for persistence and back to marks for display. You could argue “it’s open source, just write a PR”, but I’m not the only one who’s been frustrated by this https://github.com/yjs/y-prosemirror/issues/47 . The issue was closed as “Not planned”.
7 - Doc node cannot have attributes.
Also marked as closed as “not planned” https://github.com/yjs/y-prosemirror/issues/48 This is the kind of opinionated decision that makes me question some of the design decisions of Yjs. I get it, there are probably good reasons for it and technical limitations the maintainers have had to deal with. But this is the second decision that goes against ProseMirror’s design. And to be honest, we’d rather not have to work around collaboration limitations and use ProseMirror as it was designed to be used. This had us and other people consider having an extra child node of the doc that would contain the doc attributes. But this is not a very elegant solution.
8 - Alternative
- Reboot was recommended by Alex Clemmer at Moment (vid: https://www.youtube.com/watch?v=OGJxKQP7TIo ) the https://github.com/reboot-dev/reboot-prosemirror-zod They have an integration with ProseMirror that is probably worth checking out. It uses https://github.com/stepwisehq/prosemirror-collab-commit , it’s a fork of prosemirror-collab (built by Marijn Haverbeke), that batches some updates and prevents freezing from a slow client. Blogpost: https://stepwisehq.com/blog/2023-07-25-prosemirror-collab-performance/
- https://www.partykit.io/ - using cloudflare
- More info on Moment’s implementation https://gist.github.com/hausdorff/0ef41b1280c3ab3a6fe31018dd235632