Gathering detailed insights and metrics for y-prosemirror
Gathering detailed insights and metrics for y-prosemirror
Gathering detailed insights and metrics for y-prosemirror
Gathering detailed insights and metrics for y-prosemirror
npm install y-prosemirror
Typescript
Module System
Min. Node Version
Node Version
NPM Version
97.9
Supply Chain
99.2
Quality
89.1
Maintenance
100
Vulnerability
100
License
JavaScript (99.86%)
HTML (0.14%)
Total Downloads
13,622,044
Last Day
7,975
Last Week
184,019
Last Month
802,497
Last Year
7,261,820
MIT License
400 Stars
298 Commits
134 Forks
21 Watchers
5 Branches
29 Contributors
Updated on Jun 30, 2025
Minified
Minified + Gzipped
Latest Version
1.3.6
Package Id
y-prosemirror@1.3.6
Unpacked Size
286.87 kB
Size
61.33 kB
File Count
19
NPM Version
10.9.2
Node Version
22.14.0
Published on
Jun 22, 2025
Cumulative downloads
Total Downloads
Last Day
-8.8%
7,975
Compared to previous day
Last Week
-4.3%
184,019
Compared to previous week
Last Month
-3.2%
802,497
Compared to previous month
Last Year
100.4%
7,261,820
Compared to previous year
1
5
ProseMirror Binding for Yjs - Demo
This binding maps a Y.XmlFragment to the ProseMirror state.
1import { ySyncPlugin, yCursorPlugin, yUndoPlugin, undo, redo, initProseMirrorDoc } from 'y-prosemirror' 2import { exampleSetup } from 'prosemirror-example-setup' 3import { keymap } from 'prosemirror-keymap' 4.. 5 6const type = ydocument.get('prosemirror', Y.XmlFragment) 7const { doc, mapping } = initProseMirrorDoc(type, schema) 8 9const prosemirrorView = new EditorView(document.querySelector('#editor'), { 10 state: EditorState.create({ 11 doc, 12 schema, 13 plugins: [ 14 ySyncPlugin(type, { mapping }), 15 yCursorPlugin(provider.awareness), 16 yUndoPlugin(), 17 keymap({ 18 'Mod-z': undo, 19 'Mod-y': redo, 20 'Mod-Shift-z': redo 21 }) 22 ].concat(exampleSetup({ schema })) 23 }) 24})
Also look here for a working example.
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:
1example.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.
1/* this is a rough fix for the first cursor position when the first paragraph is empty */ 2.ProseMirror > .ProseMirror-yjs-cursor:first-child { 3 margin-top: 16px; 4} 5.ProseMirror p:first-child, .ProseMirror h1:first-child, .ProseMirror h2:first-child, .ProseMirror h3:first-child, .ProseMirror h4:first-child, .ProseMirror h5:first-child, .ProseMirror h6:first-child { 6 margin-top: 16px 7} 8/* This gives the remote user caret. The colors are automatically overwritten*/ 9.ProseMirror-yjs-cursor { 10 position: relative; 11 margin-left: -1px; 12 margin-right: -1px; 13 border-left: 1px solid black; 14 border-right: 1px solid black; 15 border-color: orange; 16 word-break: normal; 17 pointer-events: none; 18} 19/* This renders the username above the caret */ 20.ProseMirror-yjs-cursor > div { 21 position: absolute; 22 top: -1.05em; 23 left: -1px; 24 font-size: 13px; 25 background-color: rgb(250, 129, 0); 26 font-family: serif; 27 font-style: normal; 28 font-weight: normal; 29 line-height: normal; 30 user-select: none; 31 color: white; 32 padding-left: 2px; 33 padding-right: 2px; 34 white-space: nowrap; 35}
You can also overwrite the default Widget dom by specifying a cursor builder in the yCursorPlugin
1/** 2 * This function receives the remote users "user" awareness state. 3 */ 4export const myCursorBuilder = user => { 5 const cursor = document.createElement('span') 6 cursor.classList.add('ProseMirror-yjs-cursor') 7 cursor.setAttribute('style', `border-color: ${user.color}`) 8 const userDiv = document.createElement('div') 9 userDiv.setAttribute('style', `background-color: ${user.color}`) 10 userDiv.insertBefore(document.createTextNode(user.name), null) 11 cursor.insertBefore(userDiv, null) 12 return cursor 13} 14 15const prosemirrorView = new EditorView(document.querySelector('#editor'), { 16 state: EditorState.create({ 17 schema, 18 plugins: [ 19 ySyncPlugin(type), 20 yCursorPlugin(provider.awareness, { cursorBuilder: myCursorBuilder }), 21 yUndoPlugin(), 22 keymap({ 23 'Mod-z': undo, 24 'Mod-y': redo, 25 'Mod-Shift-z': redo 26 }) 27 ].concat(exampleSetup({ schema })) 28 }) 29})
The package includes a number of utility methods for converting back and forth between a Y.Doc and Prosemirror compatible data structures. These can be useful for persisting to a datastore or for importing existing documents.
Note: Serializing and deserializing to JSON will not store collaboration history steps and as such should not be used as the primary storage. You will still need to store the Y.Doc binary update format.
1import { prosemirrorToYDoc } from 'y-prosemirror'
2
3// Pass JSON previously output from Prosemirror
4const doc = Node.fromJSON(schema, {
5 type: "doc",
6 content: [...]
7})
8const ydoc = prosemirrorToYDoc(doc)
Because JSON is a common usecase there is an equivalent method that skips the need to create a Prosemirror Node.
1import { prosemirrorJSONToYDoc } from 'y-prosemirror' 2 3// Pass JSON previously output from Prosemirror 4const ydoc = prosemirrorJSONToYDoc(schema, { 5 type: "doc", 6 content: [...] 7})
1import { yDocToProsemirror } from 'y-prosemirror'
2
3// apply binary updates from elsewhere
4const ydoc = new Y.Doc()
5ydoc.applyUpdate(update)
6
7const node = yDocToProsemirror(schema, ydoc)
Because JSON is a common usecase there is an equivalent method that outputs JSON directly, this method does not require the Prosemirror schema.
1import { yDocToProsemirrorJSON } from 'y-prosemirror' 2 3// apply binary updates from elsewhere 4const ydoc = new Y.Doc() 5ydoc.applyUpdate(update) 6 7const node = yDocToProsemirrorJSON(ydoc)
The package exports undo
and redo
commands which can be used in place of
prosemirror-history by mapping the
mod-Z/Y keys - see ProseMirror
and Tiptap
examples.
Undo and redo are be scoped to the local client, so one peer won't undo another's changes. See Y.UndoManager for more details.
Just like prosemirror-history, you can set a transaction's addToHistory
meta property
to false to prevent that transaction from being rolled back by undo. This can be helpful for programmatic
document changes that aren't initiated by the user.
1tr.setMeta("addToHistory", false);
The MIT License © Kevin Jahns
No vulnerabilities found.
Reason
19 commit(s) and 3 issue activity found in the last 90 days -- score normalized to 10
Reason
no binaries found in the repo
Reason
license file detected
Details
Reason
8 existing vulnerabilities detected
Details
Reason
Found 4/26 approved changesets -- score normalized to 1
Reason
no effort to earn an OpenSSF best practices badge detected
Reason
project is not fuzzed
Details
Reason
branch protection not enabled on development/release branches
Details
Reason
security policy file not detected
Details
Reason
SAST tool is not run on all commits -- score normalized to 0
Details
Score
Last Scanned on 2025-06-23
The Open Source Security Foundation is a cross-industry collaboration to improve the security of open source software (OSS). The Scorecard provides security health metrics for open source projects.
Learn More