Skip to content

Vanilla JavaScript

No framework? No problem. ProseKit works with plain JavaScript out of the box via prosekit/core.

import 'prosekit/basic/style.css'
import 'prosekit/basic/typography.css'

import { defineBasicExtensionfunction defineBasicExtension(): BasicExtension
Define a basic extension that includes some common functionality. You can copy this function and customize it to your needs. It's a combination of the following extension functions: - {@link defineDoc } - {@link defineText } - {@link defineParagraph } - {@link defineHeading } - {@link defineList } - {@link defineBlockquote } - {@link defineImage } - {@link defineHorizontalRule } - {@link defineHardBreak } - {@link defineTable } - {@link defineCodeBlock } - {@link defineItalic } - {@link defineBold } - {@link defineUnderline } - {@link defineStrike } - {@link defineCode } - {@link defineLink } - {@link defineBaseKeymap } - {@link defineBaseCommands } - {@link defineHistory } - {@link defineGapCursor } - {@link defineVirtualSelection } - {@link defineModClickPrevention }
@public
} from 'prosekit/basic'
import { createEditorfunction createEditor<E extends Extension>(options: EditorOptions<E>): Editor<E>
@public
} from 'prosekit/core'
const editorconst editor: Editor<BasicExtension> = createEditorcreateEditor<BasicExtension>(options: EditorOptions<BasicExtension>): Editor<BasicExtension>
@public
({ extensionEditorOptions<BasicExtension>.extension: BasicExtension
The extension to use when creating the editor.
: defineBasicExtensionfunction defineBasicExtension(): BasicExtension
Define a basic extension that includes some common functionality. You can copy this function and customize it to your needs. It's a combination of the following extension functions: - {@link defineDoc } - {@link defineText } - {@link defineParagraph } - {@link defineHeading } - {@link defineList } - {@link defineBlockquote } - {@link defineImage } - {@link defineHorizontalRule } - {@link defineHardBreak } - {@link defineTable } - {@link defineCodeBlock } - {@link defineItalic } - {@link defineBold } - {@link defineUnderline } - {@link defineStrike } - {@link defineCode } - {@link defineLink } - {@link defineBaseKeymap } - {@link defineBaseCommands } - {@link defineHistory } - {@link defineGapCursor } - {@link defineVirtualSelection } - {@link defineModClickPrevention }
@public
() })
const rootconst root: Element | null = documentvar document: Document
**`window.document`** returns a reference to the document contained in the window. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Window/document)
.querySelectorParentNode.querySelector<Element>(selectors: string): Element | null (+4 overloads)
Returns the first element that is a descendant of node that matches selectors. [MDN Reference](https://developer.mozilla.org/docs/Web/API/Document/querySelector)
('#editor')
if (rootconst root: Element | null) { editorconst editor: Editor<BasicExtension>.mountEditor<BasicExtension>.mount: (place: HTMLElement | null | undefined) => void | VoidFunction
Mount the editor to the given HTML element. Pass `null` or `undefined` to unmount the editor. When an element is passed, this method returns a function to unmount the editor.
(rootconst root: Element as HTMLElement)
}

You're responsible for mount / unmount and any clean-up. There is no provider; pass the editor instance to anything that needs it.

editorconst editor: Editor<BasicExtension>.mountEditor<BasicExtension>.mount: (place: HTMLElement | null | undefined) => void | VoidFunction
Mount the editor to the given HTML element. Pass `null` or `undefined` to unmount the editor. When an element is passed, this method returns a function to unmount the editor.
(rootconst root: HTMLElement)
// when you're done with the editor: editorconst editor: Editor<BasicExtension>.unmountEditor<BasicExtension>.unmount: () => void
Unmount the editor. This is equivalent to `mount(null)`.
()

editor.use(extension) and the per-event handlers from prosekit/core (e.g. defineKeymap, defineDocChangeHandler) let you wire dynamic behavior without a framework.

Listen for state updates with defineUpdateHandler or the view.dom element directly:

import { defineBasicExtensionfunction defineBasicExtension(): BasicExtension
Define a basic extension that includes some common functionality. You can copy this function and customize it to your needs. It's a combination of the following extension functions: - {@link defineDoc } - {@link defineText } - {@link defineParagraph } - {@link defineHeading } - {@link defineList } - {@link defineBlockquote } - {@link defineImage } - {@link defineHorizontalRule } - {@link defineHardBreak } - {@link defineTable } - {@link defineCodeBlock } - {@link defineItalic } - {@link defineBold } - {@link defineUnderline } - {@link defineStrike } - {@link defineCode } - {@link defineLink } - {@link defineBaseKeymap } - {@link defineBaseCommands } - {@link defineHistory } - {@link defineGapCursor } - {@link defineVirtualSelection } - {@link defineModClickPrevention }
@public
} from 'prosekit/basic'
import { createEditorfunction createEditor<E extends Extension>(options: EditorOptions<E>): Editor<E>
@public
, defineUpdateHandlerfunction defineUpdateHandler(handler: UpdateHandler): PlainExtension
Registers a event handler that is called when the editor state is updated.
@public
} from 'prosekit/core'
const editorconst editor: Editor<BasicExtension> = createEditorcreateEditor<BasicExtension>(options: EditorOptions<BasicExtension>): Editor<BasicExtension>
@public
({ extensionEditorOptions<BasicExtension>.extension: BasicExtension
The extension to use when creating the editor.
: defineBasicExtensionfunction defineBasicExtension(): BasicExtension
Define a basic extension that includes some common functionality. You can copy this function and customize it to your needs. It's a combination of the following extension functions: - {@link defineDoc } - {@link defineText } - {@link defineParagraph } - {@link defineHeading } - {@link defineList } - {@link defineBlockquote } - {@link defineImage } - {@link defineHorizontalRule } - {@link defineHardBreak } - {@link defineTable } - {@link defineCodeBlock } - {@link defineItalic } - {@link defineBold } - {@link defineUnderline } - {@link defineStrike } - {@link defineCode } - {@link defineLink } - {@link defineBaseKeymap } - {@link defineBaseCommands } - {@link defineHistory } - {@link defineGapCursor } - {@link defineVirtualSelection } - {@link defineModClickPrevention }
@public
() })
editorconst editor: Editor<BasicExtension>.useEditor<BasicExtension>.use: (extension: Extension) => VoidFunction
Register an extension to the editor. Return a function to unregister the extension.
(defineUpdateHandlerfunction defineUpdateHandler(handler: UpdateHandler): PlainExtension
Registers a event handler that is called when the editor state is updated.
@public
((viewview: EditorView) => {
consolevar console: Console.logConsole.log(...data: any[]): void
The **`console.log()`** static method outputs a message to the console. [MDN Reference](https://developer.mozilla.org/docs/Web/API/console/log_static)
(viewview: EditorView.stateEditorView.state: EditorState
The view's current [state](https://prosemirror.net/docs/ref/#state.EditorState).
.docEditorState.doc: Node
The current document.
.textContentNode.textContent: string
Concatenates all the text nodes found in this fragment and its children.
)
}))

For input events, use the per-event handlers in prosekit/core, including defineKeyDownHandler, defineClickHandler, and definePasteHandler.

The pre-built UI components are shipped as native custom elements via prosekit/web/*. They work in any framework, or none at all, because they're standard Web Components. Import the component subpaths you want; each one registers its <prosekit-…> elements as a side effect.

import 'prosekit/web/menu'
import 'prosekit/web/inline-popover'