Guides
Real-time multiplayer via centralized OT (rebase / makeBias)
and a Cloudflare Worker Durable Object room.
import { Editor } from 'markloom/view'
import 'markloom/view/theme.css'
new Editor(el, doc, {
collab: {
url: 'ws://127.0.0.1:8787', // or wss://your-worker.workers.dev
room: 'demo-room',
name: 'Alice',
// token: 'secret', // when worker COLLAB_TOKEN is set
// onStatus: s => …, // connecting | open | closed | resyncing | auth-error
// onResync: v => …,
},
})
Local edits upload as Steps; remote Steps apply through OT. Presence: status dot + avatar stack + colored remote carets (auto colors by siteId).
Optional: color, seed, token / () => token,
onStatus, onResync.
Programmatic: ed.collab → CollabClient (status, pushVersion, …).
Named versions with versions: true sync over a side channel when collab is on —
see Enterprise O(1).
cd worker
bun install
bun run dev # wrangler dev → ws://127.0.0.1:8787
bun run deploy # Cloudflare account required
GET /room/:id + WebSocket upgrade → one Durable Object per room nameresync)| Direction | Types |
|---|---|
| C→S | join, op, presence, ping, version-save, version-remove |
| S→C | welcome (+versions?), op, presence, peer-join / peer-leave, resync, versions, error |
| Path | API | Undo stack | Network |
|---|---|---|---|
| local | dispatch / stream / undo / redo | commit / amend / pop | push |
| foreign | applyRemote → applyForeign | OT-map only, never push | inbound op |
Cmd+Z undoes your last commit; the inverse broadcasts as a normal op.
resync to authority (not silent corruption).COLLAB_TOKEN + client token for shared-secret auth.