Collaboration
StesuraEditor doesn’t depend on a transport. Every mount hook returns the same
{ editorState, dispatch, pluginFactory, schema }, so the backend is chosen by the hook, and the
editor, plugins and UI extensions don’t change.
Choosing a backend
| Pitter Patter | Local (offline) | |
|---|---|---|
| Sync model | Server-authoritative OT (prosemirror-collab-commit) | Same engine, authority in the browser |
| Infrastructure | Your Postgres + Redis: a route in your app, or a standalone Node server | None: IndexedDB + BroadcastChannel |
| Document store | Your database, as ProseMirror JSON | Browser IndexedDB |
| Who can co-edit | Any client | Tabs of one browser |
| Presence / cursors | ✅ | — |
| Comments | ✅ collab_thread table | ✅ IndexedDB (LocalCommentProvider) |
| Shared proofread cache | ✅ Redis | in-memory only |
| Offline editing | ❌ needs the server | ✅ |
| Hook | useCollabEditor | useLocalCollabEditor |
| Docs | Pitter Patter | Local |
For multi-user deployments, use Pitter Patter. The server is authoritative, and documents are stored as ProseMirror JSON in your own Postgres, where you can audit, query and back them up. We don’t use a CRDT: document editing rarely needs peer-to-peer merging, and bridging a CRDT to ProseMirror costs whole-document remote transactions (which break decorations), slow undo on long documents, and no marks on nodes or attributes on the doc node. See Why we’re moving away from Yjs .
Use Local when there is no server: local-first or desktop-style apps. Tabs co-edit in real time, and every confirmed keystroke is persisted.
The common shape
const { editorState, dispatch, pluginFactory, schema } = useCollabEditor({ ... });
// or useLocalCollabEditor({ ... }) / useLocalEditor({ ... })
<StesuraEditor
state={editorState}
dispatchTransaction={dispatch}
schema={schema}
pluginFactory={pluginFactory}
nodeViews={stesuraNodeViews}
uiExtensions={uiExtensions}
/>On both backends:
- Undo reverts only your own edits.
prosemirror-historystays enabled: the collab plugin marks remote transactions so history skips them. - Comments go through a
CommentAdapter, which each backend wires. See Comments.
Next steps
- Pitter Patter: client mount, server setup, presence, comments, shared proofread cache, deployment.
- Rooms: multi-document suites.
- Backend API: reading and editing documents from server code.
- Server edits: editing documents from server code.
- Local: offline multi-tab editing over IndexedDB.
- Live demos: Pitter Patter , IndexedDB .