Multiplayer
The Multiplayer kit turns the editor into a real-time collaborative canvas using
@oh-just-another/collab โ a CRDT layer built on Yjs โ paired with a transport
from @oh-just-another/network. Multiple peers edit one scene; cursors and
selections from other peers paint into the canvas as presence.
Wiring it upโ
SceneDoc is a CRDT-backed mirror of a Scene over a Y.Doc. bindEditor
keeps the live editor and the SceneDoc in sync (self-origin filtered so writes
do not ricochet). bindAwareness publishes the local cursor/selection and paints
peers back. A TransportProvider bridges the doc onto a transport.
import * as Y from "yjs";
import {
SceneDoc,
CollabAwareness,
TransportProvider,
bindEditor,
bindAwareness,
} from "@oh-just-another/collab";
import { BroadcastChannelTransport } from "@oh-just-another/network";
const doc = new Y.Doc();
const sceneDoc = new SceneDoc(doc);
const awareness = new CollabAwareness(doc);
const transport = new BroadcastChannelTransport("room-foo");
const provider = new TransportProvider({ doc, transport, awareness: awareness.awareness });
const unbindScene = bindEditor(editor, sceneDoc);
const unbindPresence = bindAwareness(editor, awareness, {
user: { id: "me", name: "Alice", color: "#1a73e8" },
});
// teardown
// unbindPresence(); unbindScene(); provider.destroy();
// awareness.destroy(); transport.close(); doc.destroy();
Transportsโ
Swap the transport for the topology you need: BroadcastChannelTransport for
tabs on one machine, WebSocketTransport for cross-machine sessions via a relay.
Encryption (blind relay)โ
EncryptedTransport (exported from @oh-just-another/collab) wraps any
transport so the relay sees only ciphertext. Mint credentials with
generateRoomKey() and keep the AES key in the URL fragment โ
which browsers never transmit โ so the relay routes by roomId without ever
seeing plaintext. The playground's collab demo does exactly this: roomId rides
the WebSocket path, the key lives in location.hash, and every Yjs/awareness
frame goes through EncryptedTransport (AES-GCM, random IV per frame).
Also availableโ
@oh-just-another/collab ships branch-and-merge (BranchDoc, three-way merge),
CRDT-aware undo scoped to the local client (CollabHistory), and @handle
mentions (extractMentions, resolveMentions, notifyMention).
Statusโ
The pattern above uses only shipped exports. A packaged, cloneable
Multiplayer starter template (relay server plus client wiring as one repo)
does not exist yet. Generic starters that mount <Editor> live in
templates/.