y-codemirror
CodeMirror Binding for Yjs - Demo
This binding binds a Y.Text to a CodeMirror editor.
Features
- Sync CodeMirror editor
- Shared Cursors
- Shared Undo / Redo (each client has its own undo-/redo-history)
- Successfully recovers when concurrents edit result in an invalid document schema

Example
import * as Y from 'yjs'
import { CodemirrorBinding } from 'y-codemirror'
import { WebrtcProvider } from 'y-webrtc'
import CodeMirror from 'codemirror'
const ydoc = new Y.Doc()
const provider = new WebrtcProvider('codemirror-demo-room', ydoc)
const yText = ydoc.getText('codemirror')
const yUndoManager = new Y.UndoManager(yText)
const editor = CodeMirror(editorDiv, {
mode: 'javascript',
lineNumbers: true
})
const binding = new CodemirrorBinding(yText, editor, provider.awareness, { yUndoManager })
Also look here for a working example.
API
const binding = new CodemirrorBinding(yText: Y.Text, editor: CodeMirror.Editor, [ awareness: y-protocols.Awareness|null, [ { yUndoManager: Y.UndoManager } ]])
Binds a Y.Text type to the CodeMirror document that is currently in use. You can swapDoc
the CodeMirror document while a binding is active. Make sure to destroy a binding when it is no longer needed.
When Y.UndoManager
is defined, y-codemirror will use a custom collaborative undo manager instead of CodeMirror's UndoManager. The collaboration-aware Y.UndoManager tracks only local changes by default and doesn't track changes from remote users. You should undo/redo changes using yUndoManager.undo()
/ yUndoManager.redo()
instead of using CodeMirror's history manager. See the extensive documentation on Y.UndoManager
for documentation on how to filter specific changes.
destroy()
-
Destroy the CodemirrorBinding, remove all event listeners from the editor and the Yjs document, and destroy the UndoManager.
cm: CodeMirror.Editor
-
Reference to the CodeMirror editor.
cmDoc: CodeMirror.Doc
-
Reference to the CodeMirror document.
type: Y.Text
-
Reference to the Y.Text type that this binding binds to.
doc: Y.Doc
-
Reference to the Yjs document.
awareness: y-protocols.Awareness
-
Reference to the Awareness instance, if defined.
on('cursorActivity', (editor: CodeMirror) => void)
-
This event is similar to CodeMirror's 'cursorActivity' event, but is fired
after all changes have been applied to the editor and to the Y.Text instance.
The shared cursors depend on the Awareness instance that is exported by most providers. The Awareness protocol handles non-permanent data like the number of users, their user names, their cursor location, and their colors. You can change the name and color of the user like this:
example.binding.awareness.setLocalStateField('user', { color: '#008833', name: 'My real name' })
In order to render cursor information you need to embed custom CSS for the user icon. This is a template that you can use for styling cursor information.
.remote-caret {
position: absolute;
border-left: black;
border-left-style: solid;
border-left-width: 2px;
height: 1em;
}
.remote-caret > div {
position: relative;
top: -1.05em;
font-size: 13px;
background-color: rgb(250, 129, 0);
font-family: serif;
font-style: normal;
font-weight: normal;
line-height: normal;
user-select: none;
color: white;
padding-left: 2px;
padding-right: 2px;
z-index: 3;
}
License
The MIT License © Kevin Jahns