Collaborative Editing
Real-time collaboration using Yjs CRDTs with CodeMirror 6. Two editors sharing the same document state.
Live Demo
Both editors below share the same Yjs document. Type in either one — changes sync instantly to the other. This is a client-side-only demo (no server).
Connecting...
User A Editor 1
User B Editor 2
Shared Document State
How It Works
Editor 1 CodeMirror 6
y-codemirror.next
Y.Doc CRDT State
y-codemirror.next
Editor 2 CodeMirror 6
The Yjs document (Y.Doc) is the single source of truth. Both CodeMirror instances bind to the same Y.Text type. Edits in one editor are automatically reflected in the other via Yjs's CRDT algorithm.
Integration Code
typescript
import * as Y from 'yjs';
import { yCollab, yUndoManagerKeymap } from 'y-codemirror.next';
import { WebsocketProvider } from 'y-websocket';
// 1. Create shared document
const ydoc = new Y.Doc();
const ytext = ydoc.getText('codemirror');
// 2. Connect to a server (or use WebRTC for P2P)
const provider = new WebsocketProvider(
'wss://your-server.com', 'room-name', ydoc
);
// 3. Create awareness (cursor positions, user info)
const awareness = provider.awareness;
awareness.setLocalStateField('user', {
name: 'User A',
color: '#3b82f6'
});
// 4. Add yCollab extension to CodeMirror
const extensions = [
// ... other extensions
yCollab(ytext, awareness, {
undoManager: new Y.UndoManager(ytext)
}),
keymap.of(yUndoManagerKeymap)
];CRDT vs OT
typescript
// CRDT: Conflict-free Replicated Data Type
//
// Traditional approach (OT - Operational Transform):
// Client A: insert 'x' at position 5
// Client B: delete char at position 3
// Server: transform operations to resolve conflicts
//
// CRDT approach (Yjs):
// Each character has a unique ID
// Operations reference IDs, not positions
// Merging is automatic and deterministic
// No server needed for conflict resolution
//
// Yjs data types:
// Y.Text → collaborative text (used with CodeMirror)
// Y.Array → collaborative array
// Y.Map → collaborative object
// Y.XmlFragment → collaborative rich text (ProseMirror)| Aspect | OT (Operational Transform) | CRDT (Yjs) |
|---|---|---|
| Server requirement | Required for transformation | Optional (P2P possible) |
| Conflict resolution | Server transforms operations | Automatic, deterministic |
| Offline support | Limited | Full (sync on reconnect) |
| Complexity | Server-side logic complex | Client-side, simpler server |
| Used by | Google Docs, ProseMirror collab | Yjs ecosystem, BlockSuite |
| Memory overhead | Low | Higher (stores history) |
Yjs Ecosystem
y-codemirror.next
CodeMirror 6 binding — cursor awareness, undo manager, text sync
y-prosemirror
ProseMirror binding — rich text collaboration with schema support
y-websocket
WebSocket provider — server-based sync with persistence
y-webrtc
WebRTC provider — peer-to-peer sync, no server needed
y-indexeddb
IndexedDB provider — offline persistence in the browser
y-protocols
Encoding/decoding protocols for custom transport layers