Skip to content

Architecture

prosekit/core is a small, type-safe layer on top of ProseMirror. This page shows how every editor is put together.

You combine extensions with union(...) and pass the result to createEditor({ extension }). You get back an Editor whose commands, nodes, marks, and view are typed from the extensions you passed in.

import { createEditorfunction createEditor<E extends Extension>(options: EditorOptions<E>): Editor<E>
@public
, unionfunction union<const E extends readonly Extension[]>(...exts: E): Union<E> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```@public
} from 'prosekit/core'
import { defineDocfunction defineDoc(): DocExtension
@public
} from 'prosekit/extensions/doc'
import { defineParagraphfunction defineParagraph(): ParagraphExtension
@publicDefines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
} from 'prosekit/extensions/paragraph'
import { defineTextfunction defineText(): TextExtension
@public
} from 'prosekit/extensions/text'
const extensionconst extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension]> = unionunion<readonly [DocExtension, TextExtension, ParagraphExtension]>(exts_0: DocExtension, exts_1: TextExtension, exts_2: ParagraphExtension): Union<readonly [DocExtension, TextExtension, ParagraphExtension]> (+1 overload)
Merges multiple extensions into one. You can pass multiple extensions as arguments or a single array containing multiple extensions.
@throwsIf no extensions are provided.@example```ts function defineFancyNodes() { return union( defineFancyParagraph(), defineFancyHeading(), ) } ```@example```ts function defineFancyNodes() { return union([ defineFancyParagraph(), defineFancyHeading(), ]) } ```@public
(
defineDocfunction defineDoc(): DocExtension
@public
(),
defineTextfunction defineText(): TextExtension
@public
(),
defineParagraphfunction defineParagraph(): ParagraphExtension
@publicDefines a paragraph node. The paragraph node spec has the highest priority, because it should be the default block node for most cases.
(),
) const editorconst editor: Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>> = createEditorcreateEditor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>(options: EditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>): Editor<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>
@public
({ extensionEditorOptions<Union<readonly [DocExtension, TextExtension, ParagraphExtension]>>.extension: Union<readonly [DocExtension, TextExtension, ParagraphExtension]>
The extension to use when creating the editor.
})

An extension is an object that holds part of the editor: a schema, commands, keymaps, plugins, or any mix of these. You never build one by hand. You call a define* function, and you combine extensions with union(...). The functions come at different levels of abstraction. Here are three examples:

  • defineNodeSpec() wraps a single ProseMirror node spec and adds nothing else.
  • defineHeading() bundles the heading node spec with its commands, keymaps, and input rules, so one call gives you the full heading feature.
  • defineBasicExtension() is a pre-bundled set of extensions that gives you a working editor out of the box including paragraphs, headings, lists, code blocks, and more.

Pick the level that fits your need. Most app code starts with defineBasicExtension() and adds individual feature extensions.

  • The Editor: what the Editor instance exposes.
  • Extensions: how to compose them.
  • Schema: nodes and marks.
  • Commands: how to run and check commands.
  • Content: convert between JSON, HTML, and ProseMirror nodes.
  • Views: node views, mark views, decorations.