npm / @tiptap/core
@tiptap/core
What changed in @tiptap/core 2 to 3, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-19.
5 breaking1 security28 new APIs and options2 performance4 behavior and defaults37 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli init@tiptap/core 368 changes
Breaking changes 2
Node view
getPos()returnsundefinedwhen its position cannot yet be resolved, rather than throwing.When attributes are omitted, extendMarkRange uses the first mark's attributes; passing an empty object restores the previous behavior.
Security 1
Adds a chainable extension API to transform pasted HTML before it is parsed, enabling cleanup, removal of dangerous content, and other modifications.
New APIs and options 24
New helpers check whether a value is a specific ProseMirror type.
Extensions can declare decorations directly through a hook, avoiding a hand-written ProseMirror plugin and plugin-state mapping.
With update set to 'changedRanges', rescans only blocks that actually changed instead of rebuilding decorations across the whole document.
Adds inline decorations for styling a range of text.
Adds node decorations for putting attributes on a block’s DOM element.
Adds widget decorations that render a custom element at a single position.
Adds a helper that returns the block-level sibling before the cursor’s textblock, or null at the first child of the block parent.
Widgets accept the ProseMirror ignoreSelection option.
Adds a renderer for React components in widget decorations that keeps them inside the existing app context.
Widgets accept the ProseMirror relaxedSide option.
Lets decoration implementations skip transactions that do not affect the data they depend on.
Widgets accept the ProseMirror side option.
Widgets accept the ProseMirror stopEvent option.
With update set to 'manual', decorations driven by external data can be refreshed through an editor command.
Adds a renderer for Vue components in widget decorations that keeps them inside the existing app context.
Adds a command to insert the default textblock allowed at a position, with optional position, attributes, content, and selection-update options.
Ordered lists preserve their HTML type through round-trips; paste and Markdown recognize typed markers, and adjacent lists with different types are not merged.
Adds a utility that compares two attribute objects for equality regardless of key ordering.
Adds the
clearablemark option, defaulting totrue;unsetAllMarksskips marks set tofalse.Adds a utility that compares arrays of mark objects by type and attributes using
attrsEqual.This opt-in option makes the component re-render on every position shift so calls to getPos() stay current in render output.
Adds a utility for handling style properties, used by several extensions.
Adds an option to node view renderers that makes the selected prop true when a TextSelection is fully inside the node's range, as well as on NodeSelection.
Global attributes accept shorthand string values for
types:'*'applies to all nodes and marks,'nodes'to all nodes excluding text, and'marks'to all marks.
Performance 1
NodeViews no longer re-render when decorations or position change without content changes.
Behavior and default changes 3
Reusing a widget key keeps the component instance mounted while the document changes around it, preserving local state.
ListKeymap registers a Tab shortcut that moves a top-level textblock at the start of the paragraph into the previous list’s last item.
Markdown encoding detection now checks the extension spec's code flag rather than hardcoded type names, affecting which content is skipped during encoding.
Fixes and other changes 37
Nested sibling elements now render properly by spreading children arrays into DOMOutputSpec.
editor.chain and editor.can can now be accessed during editor initialization.
Mixed JSX children are kept as separate siblings in DOM output.
Fixes failures when prosemirror-model is loaded more than once.
Fixes failures when prosemirror-model is loaded more than once.
Fixes failures when prosemirror-model is loaded more than once.
Deleting an
AllSelectionnow collapses the selection to a text cursor instead of leaving a phantom selection highlight.editor.$pos()now returns the correct node inside container nodes, such as the list rather than the list item.Input rules no longer crash when matched text spans an inline atom node, such as a mention.
Changed the platform comparison to use
.includes(), avoiding a TypeScript build error with somelib.dom.d.tstypings; runtime behavior is unchanged.The editor now has a usable state seeded from the stripped fallback document before
onContentErrorfires, allowing commands to be called in the handler on initial load.deleteSelection now deletes content across all selection ranges instead of only the first, restoring multi-cell table selections and other custom selections with multiple ranges.
Compares mark arrays as multisets, so mark order does not affect equality; its type signature also accepts ProseMirror Mark objects.
Supports word characters at the start of class and id attributes.
Handles null-ish values inside marks or nodes without failing.
Dragging an inline or resizable image within the editor moves it instead of inserting a duplicate.
Plain-text copies of table cell selections exclude unselected cells between selected ranges and preserve document order for reverse selections.
Deletion now expands the selection to include entire inline node boundaries when handling inline nodes with text* content, preventing incorrect collapse of inline text nodes.
$pos() now returns the correct node for non-text atom nodes instead of the doc node.
Fixes HTML entity encoding for inline style attributes in getHTML() output.
Fixes text selection collapsing after toggling off a list with AllSelection.
Fixed document corruption when inserting inline content with marks at the start of a paragraph; the from - 1 position adjustment now applies only to block-level content.
Fixes list toggling when the entire document is selected.
Pasting at the end of a marked text node now places the selection correctly and respects inclusive marks.
NodeViews now re-render when a node's position changes without content or decoration changes, such as when a sibling moves within the same parent.
NodeViews no longer stop dragover and dragenter events, preventing spurious drag-copy cursors.
The default attributes are now considered against the first mark of the given type.
Markdown parsing decodes common HTML entities; serialization re-encodes <, >, and &, while preserving double quotes and literal characters inside code.
ResizableNodeView now respects a node's inline setting by using inline-flex for inline nodes and flex for block nodes.
Mark delete event handling is guarded when unsetMark removes a mark from inline content starting at position 0, preventing a RangeError.
Fixed isNodeEmpty() so multiline text containing non-whitespace content is not treated as empty when ignoreWhitespace is enabled.
Fixed overlapping bold and italic markdown serialization and round-tripping.
Empty paragraphs in top-level and nested block content now serialize with natural blank-line spacing or markers, and parsing preserves them when converting markdown back to JSON.
Fixes inline style parsing for values containing
:or;and skips incomplete declarations.Fixes checking whether a mark is active and toggling marks off when part of the selection does not allow the mark, such as in a code block.
Fixed the ResizableNodeView contentDOM getter to return null instead of undefined for TypeScript compatibility.
Fixed $nodes() to correctly return inline nodes such as text and mention nodes.
@tiptap/core 29 changes
Breaking changes 3
The command now emits updates by default.
The command no longer splits text nodes at the beginning.
The signature is now (content, options), and the command emits updates by default.
New APIs and options 4
Mark.create can define a mark view to render custom views for marks within the editor.
New delete event tracking is available.
Setting element to null opts into creating an editor on the server without rendering.
Support for validating node and mark attributes is added.
Performance 1
Transaction handling has performance improvements.
Behavior and default changes 1
The NodeViewRendererProps function can now return undefined, so callers should handle that case.