npm / lexical
lexical
What changed in lexical 0.38 to 0.52, from its official release notes, upgrade guides and advisories. Sources checked 2026-10-18.
61 breaking2 security22 deprecations113 new APIs and options6 performance70 behavior and defaults2 tooling146 fixes and other
See which of these apply to your code, ranked, in your agent:
npx @unstale/cli initlexical 0.5220 changes
Breaking changes 4
Works with buildEditorFromExtensions for server-side processing and tests, marks the editor headless, prevents attaching a DOM root, and keeps listener registration methods available.
Removed; use $getCommonAncestor(a, b)?.commonAncestor ?? null, passing parents of non-element nodes when the old behavior is needed.
Replace this deprecated output type with MdastExtensionOutput.
Replace this deprecated output type with MdastExtensionOutput.
Deprecations 2
Deprecated alias of MdastExtension; move configuration to MdastExtension.
Deprecated alias of MdastExtension; move configuration to MdastExtension.
New APIs and options 2
Import/export middleware can delegate conversion of the same node to remaining handlers, then return or modify their output; null and [] retain distinct meanings.
A unified Markdown extension now owns import and export; feature extensions include it automatically, and export rules can target node classes or type strings and apply to subclasses.
Behavior and default changes 2
Default HTML export now honors DOMRenderExtension $createDOM overrides, which can change exported HTML for nodes inheriting or calling the default export.
The command now runs before DOM reconciliation inside the pending writable update; selection reads, listener edits, tags, and error handling follow that update's contract.
Fixes and other changes 10
Dropping dragged text on the edge of its own selection no longer deletes it.
Backspace over all text in the first block preserves the empty block and its type.
Focus commands triggered during DOM selection synchronization no longer produce spurious read-only warnings; dispatching from an explicit read context still warns.
Lexical-controlled caret moves reveal the caret in code blocks and other horizontally scrolling containers, including table wrappers; scrolling respects scroll-padding.
The workaround after handled Backspace or select-all is limited to macOS Chromium, preventing legitimate text input from being discarded on other platforms.
iOS tracks explicit Shift key events so Shift+Enter can insert a line break without treating automatic capitalization as Shift.
Correctly resolves endpoints inside text-bearing inline decorators.
Highlights retain coverage across mixed font sizes and partially overlapping rectangles.
Restores an editable paragraph when the root still contains slots such as footnotes.
A childless root now warns and recovers to an empty paragraph in production; development builds still report the invalid state through onError.
lexical 0.5119 changes
Breaking changes 5
A production import of only createCommand no longer retains the editor.
npm packages are ESM-only and provide no require export condition. CommonJS consumers need Node.js 20.19+ or dynamic import; load shared dependencies as ESM to avoid duplicate instances.
A property declared with withField is read directly from the node, so exportJSON no longer resolves getLatest() for a retained reference. Call getLatest() yourself after mutations.
Deprecated Prism re-exports and the @lexical/code-prism dependency are removed. Import the listed Prism utilities from @lexical/code-prism instead.
Merging cells no longer keeps the empty paragraph of the target cell.
Deprecations 1
LexicalComposer is deprecated in favor of LexicalExtensionComposer; it cannot accept extensions and is expected to be removed in a future major.
New APIs and options 4
Flow declarations can now express an extension with dependencies.
The package now publishes one subpath export per extension, such as @lexical/extension/AutoFocusExtension; the barrel import is unchanged.
Declarative serialization schemas let nodes using $config declare serialized properties once, driving importJSON, updateFromJSON, and exportJSON; most custom nodes no longer need JSON serialization code.
editorState.toJSON(true) opts into compact JSON export, omitting schema-default properties, parser-derived properties, and the deprecated version field. Compact JSON requires readers that know the schemas.
Performance 1
Built-in node classes ship with straight-line serialization generated from their schemas at build time, providing faster import and export with byte-identical JSON to the schema-driven path.
Behavior and default changes 2
Selection overlay listeners are now notified when rectangles are removed.
A text entity now keeps the style and detail of the text it replaces.
Fixes and other changes 6
Flow types now allow defineExtension to be called, making extension types usable.
Text left outside a Markdown link now keeps its format.
Indenting between two nested lists no longer converts the second list's type.
Removing text from a caret range no longer leaves a childless list or table as the root's only child.
Safari link selection no longer dispatches a redundant selection-change command.
setMode, setTextContent, and isSimpleText now read the latest state.
lexical 0.5056 changes
Breaking changes 10
A getXmlText or getXmlElement result with an un-integrated or misnamed type now throws an invariant instead of failing later.
The Lexical JSON clipboard payload now calls excludeFromCopy with 'clone' instead of 'html', so custom implementations keyed on 'html' for this channel should be updated.
An insertText anchor that is not a text node now throws an invariant instead of failing later.
An empty KeyboardShortcutMatch key now throws an invariant instead of failing later.
Yjs collaboration no longer syncs root textFormat or textStyle.
Replacing a named slot value through the tree API now fails with an actionable invariant; use $setSlot on the owning host instead.
No longer re-homes named slots when replacing a node, which can affect code relying on slots moving to the replacement.
Only RootListener and EditableListener are typed to return cleanup functions; returning one from another listener is now a TypeScript error.
Now rejects an empty selector group.
Deleting or cutting a whole-document selection now removes top-level blocks, leaving a fresh empty paragraph; Cmd+X carries those blocks so pasting restores them.
Deprecations 4
Deprecated in favor of the canRedo signal on HistoryExtension, which holds the current value for listeners registered after initialization.
Deprecated in favor of HistoryExtension signals.
Deprecated in favor of the canUndo signal on HistoryExtension, which holds the current value for listeners registered after initialization.
Deprecated in favor of HistoryExtension signals.
New APIs and options 16
Announces to screen readers when typing turns text into a link and is enabled by default with AutoLinkExtension.
Adds compiled keyboard shortcut dispatch and related core constants and platform-mask helper for declaring and matching shortcuts.
Supports custom Yjs XmlText through CreateBindingV2Options__EXPERIMENTAL, allowing a Lexical document inside a larger shared type.
Allows a custom Yjs XmlText so a Lexical document can live inside a larger shared type.
Adds a new core export for accessing the selection slot frame.
Announces heading changes to screen readers and is enabled by default through RichTextExtension.
Keeps an editor alive across hot module replacement, with HMRConfig, HMROutput, and HotContext.
Adds an extension for declaring named keyboard shortcuts and formatting them for the current platform.
Markdown import restructures nested mixed-type lists and stores code-fence metadata in a new mdCodeMeta node state.
Adds a config option that lets files take precedence over incidental HTML when pasting.
Accepts an optional third argument to let an app decide whether pasted files take precedence over incidental text/html.
Adds a rich-text configuration callback so an app can decide whether pasted files take precedence over incidental text/html; the default remains unchanged.
Adds an opt-in overlay for pasted Word lists.
An opt-in extension reconstructs list structure from Microsoft Word HTML on paste.
Opt-in support reconstructs list structure from Microsoft Word HTML on paste.
Allows a custom Yjs XmlText to be used for collaboration.
Performance 1
Bulk inserts and removals no longer walk parent children to compute an unused selection offset, avoiding quadratic operations.
Behavior and default changes 9
Prioritizes file transfer over text/html when pasting browser-copied images.
Rich text announces heading changes by default for accessibility.
JSON deserialization now builds through $create, applying registered node replacements and running the replacement class's importJSON.
Moves into core and remains re-exported from @lexical/utils.
Builds nodes with $create when importing JSON, applying node replacements during import.
Screen reader users are told when typing turns text into a link.
Middle-clicking links now opens them in a new tab.
RichTextExtension enables heading and auto-link screen reader announcements by default through a live region appended to document.body or the configured owner; announcements can be disabled.
Applying a link to a NodeSelection now applies the title attribute.
Tooling 1
A new Rollup and Vite plugin injects pure annotations and inlines trivial side-effect-free factories at build time, removing the need for hand-written annotations on those calls.
Fixes and other changes 15
Newly inserted AutoLinkNode instances now keep the original node's properties.
Cloning an EditorState now keeps _parsed.
When exportDOM returns a DocumentFragment, its after() replacement is now applied.
A trailing LineBreakNode in a block exports an extra managed <br>, matching the live DOM so the line break survives export/import round trips.
Inserting a block at the end of a paragraph no longer leaves an empty paragraph behind.
Inserting text no longer throws when the caret is inside a segmented TextNode.
LinkNode and AutoLinkNode getters now read the latest state.
A fully selected paragraph with alignment, indent, or inline style remains a block in copied content instead of losing its formatting.
Replacing a node with a sibling now keeps the parent's size correct.
Now forwards the parent's maxDepth to shared history.
Shared history stacks now record the state of the editor that actually changed.
Only one client may bootstrap a nested editor's document, preventing a spurious leading paragraph in image captions or sticky notes.
Reinserting a node after a range no longer creates a sibling cycle.
The object payload no longer discards configured link attributes.
The object payload no longer discards configured link attributes.
lexical 0.4925 changes
Breaking changes 5
Built-in node classes now use the $config protocol; ported nodes no longer have static importJSON, importDOM, clone, or transform methods. Use the higher-level equivalents instead.
Unrestricted CSS selector groups are now evaluated against all elements instead of only tag-matched elements.
The helper was renamed from isNestedListNode to follow the dollar-prefixed naming convention.
Typing a list marker at the start of a heading no longer converts the heading into a list.
The node type field is now readonly, and built-in node constructors require zero-argument defaults.
Deprecations 2
Deprecated in favor of $createTableSelectionFrom, which takes the table node and anchor/focus cells and validates them.
Deprecated because it computes incorrect bounds for merged cells; use $computeTableCellRectBoundary with $computeTableMap instead.
New APIs and options 5
Use this newly exported alias instead of unsafe LexicalCommand<unknown> usage now that LexicalCommand payload types are invariant.
Now exported for computing table cell rectangle boundaries; use it with $computeTableMap instead of getShape.
Creates a table selection from the table node and anchor/focus cells, validating them instead of returning a blank selection with placeholder root keys.
Set this table config option to true to keep the horizontal scrollbar for overflowing tables anchored at the viewport bottom.
Use this new theme key to style the sticky horizontal scrollbar for tables.
Behavior and default changes 2
The table DOM omits colgroup when column widths are undefined, allowing browser auto-sizing, and creates or removes it dynamically as widths change.
The payload argument is optional when a command's payload type is undefined or void.
Fixes and other changes 11
Pressing ArrowUp before a leading non-inline decorator no longer moves the selection out of the editor.
The synthesized clone now applies afterCloneFrom when called directly, preventing silent property loss across core nodes.
Cmd/Ctrl-based delete-line shortcuts now work inside table cells instead of being swallowed.
Updates dispatched from a read-only context now run in a fresh writable update instead of being dropped, with a development warning.
Firefox now creates a selection and shows the block cursor when clicking in the gap between block decorators.
The synthesized getType no longer returns a superclass type when inherited or recurses infinitely when copied onto a subclass, fixing node-type collisions and compiled-build stack overflows.
QuoteNode.updateDOM now accepts the EditorConfig argument passed by the reconciler, matching other nodes.
Redundant explicit type parameters were dropped from registerCommand call sites.
Redundant explicit type parameters were dropped from registerNodeTransform call sites.
Concurrent asynchronous language and theme loads are deduplicated and merged into one history entry, avoiding spurious undo states.
Alignment now works when cells are selected in any direction, not only top-left to bottom-right.
lexical 0.4816 changes
Breaking changes 1
Unparseable URLs now fail closed, preventing a potential XSS vector.
Security 1
Fixed a dependency vulnerability.
New APIs and options 3
Added an extension for extending the Markdown ↔ mdast pipeline with custom constructs.
Added a helper for reordering table rows.
The shared-type root name is customizable, allowing Lexical to share a Yjs document with content that uses a different root key.
Behavior and default changes 3
Backspace now outdents the item or converts it to a paragraph.
The table auto-scrolls when drag-selecting cells past the visible edge.
Tables can now be copied in read-only mode.
Fixes and other changes 8
Block separators are counted when wrapping character-limit overflow.
Code is re-tokenized after an asynchronous language load so highlighting appears when the grammar is ready.
Disabled autolinks no longer open links.
Overlapping inline formats now roundtrip correctly through mdast and Markdown.
Text dragovers are no longer canceled, restoring native text drops.
Skips
scrollIntoViewIfNeededwhen the selection rectangle is above the editor, fixing a Safari RTL caret jump.Added the previously missing export for
$unmergeCellNode.Adjacent
OverflowNodes are merged inuseCharacterLimit.
lexical 0.4724 changes
Breaking changes 3
No longer removes adjacent block decorators.
React 18 is now the minimum supported version; react and react-dom peerDependencies require >=18, and React 17 compatibility code paths were removed.
Sets the selection's text format instead of toggling it.
New APIs and options 8
Parses a Markdown string into Lexical nodes without inserting them into the document or modifying the selection.
Returns the owner document of the active editor, including in a Shadow DOM or iframe, and falls back to the global document when there is no active editor.
Exports the table-column insertion utility.
Exports the table-row insertion utility.
Adds a type-safe addEventListener helper that returns a cleanup function.
Adds type-safe addEventListener helpers that return cleanup functions.
Adds a utility for setting whether a table column is a header.
Adds a utility for setting whether a table row is a header.
Behavior and default changes 2
Defers onUpdate callbacks during nested commits.
Pasted TSV text now spreads across table cells.
Fixes and other changes 11
ArrowUp and ArrowDown no longer skip block decorators.
Fence-like lines inside a code block stay content, and formatting is prevented on TabNode inside code blocks.
No longer overwrites the X11 PRIMARY selection via Selection.modify.
Prevents text duplication on iOS Safari when formatting during composition.
Fixes navigation across unmergeable TextNode boundaries in inline-grid containers.
Re-resolves a detached firstBlock.
Properly handles block-end focus in backward selections.
Keeps the selection inside single-child inline elements.
Deduplicates speech-to-text insertion on Android Chrome.
A segmented TextNode temporarily switches to normal mode during IME composition, preserving its node key and DOM element until composition ends.
Skips zero-width space insertion for format mismatch on Android Chrome.
lexical 0.4651 changes
Breaking changes 12
A subset of exports deprecated in v0.32.1 has been removed from lexical-link, lexical-list, and lexical-react, so imports of those exports must be updated.
Copying or exporting a
NodeSelectioncontaining anElementNodenow includes its children instead of serializing a childless shell.Passing the root element now resolves to
RootNodeinstead ofnull; external callers relying onnullmust update. Selection capture also applies to any subtree marked withsetDOMUnmanaged.Moves getScrollParent to @lexical/utils, changing the package from which consumers import it.
The deprecated export was removed; use
$insertListfrom an update or command listener.The boundary no longer wraps
react-error-boundaryand accepts an optionalfallbackprop; omitting it uses the default message, whilenullrenders nothing.Code spans now bind tighter than text-match transformers, and inline code spans can contain backticks.
The
ContentEditablePropstype alias was removed; useContentEditableProps.The method was replaced by
editor.read('pending', fn), which reads pending state without flushing.The deprecated export was removed; use
$removeListfrom an update or command listener.The function takes a new
dirtyLeavesparameter betweendirtyElementsandnormalizedNodesto represent slot-host values.The deprecated export was removed; use
$toggleLinkinstead.
Security 1
CSS parsing is faster, and regexes and prototype handling are hardened against ReDoS and prototype pollution.
Deprecations 7
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
Traversal methods now expose non-generic base-type signatures; unsafe generic overloads are deprecated. Replace contextual-type assignments with explicit casts or type guards.
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
The standalone import extension is now a deprecated alias; its removal may come as early as v0.47.0.
New APIs and options 10
The playground adds Korean IME autocomplete with composition-idle ghost text and a pluggable dictionary.
The configuration protocol supports shared abstract-base configuration and accessor-based nominal typing for stricter subclass checks.
A new helper removes zero-area and contained client rects, cleaning up duplicate or spurious WebKit fake-selection rectangles.
Supports DOM shadow roots through platform selection APIs.
When enabled, arrowing past the end of a terminal code block creates a paragraph and moves the caret into it; the option defaults to false.
Go is now available as a code-language option.
Experimental opt-in slots let a host node own multiple isolated editable regions inside its editor state.
The playground can display non-printing marks, toggled from Settings.
A new optional editor hook handles warnings; the infinite-update-loop guard routes its recoverable warning through it.
Adds block-first select-all behavior, with an opt-in
cascadeSelectionoption for nested editors; select-all is a no-op when everything is already selected.
Behavior and default changes 6
Nodes can be inserted at the block cursor inside a shadow root.
Remote collaborator selections are painted with the CSS Custom Highlight API, retaining the positioned overlay only as a fallback.
Cut-tagged updates receive their own history entry instead of merging with preceding or following keystrokes.
Node-providing extensions now register their own DOM import rules, removing the need to list per-package import extensions for the experimental pipeline.
MarkNode method return types are widened to boolean, affecting type expectations for callers.
Paste-tagged updates receive their own history entry instead of merging with preceding or following keystrokes.
Fixes and other changes 15
Markdown round-tripping now preserves block equations.
Ignores beforeinput and input events in captured decorators.
Exiting a nested code block no longer creates a duplicate paragraph.
Backspace at the start of a top-level list now preserves the preceding
DecoratorNode.Adds a utility to deduplicate selection rectangles and fix duplicate or extra rectangles on WebKit.
Markdown parsing handles inline code spans that contain backticks.
Preserves inline formatting when already-formatted text is wrapped with matching markers.
Inserting inline content ahead of a block now preserves the first
LineBreakNodeinstead of dropping it.Refreshes the iOS keyboard suggestion bar after Backspace for all locales.
Copying links in Firefox and Safari now preserves the
LinkNodewrapper.Preserves LinkNode wrapping when copying in Firefox and Safari.
Method return types are widened to
boolean, allowing subclass overrides.Normalizes non-inline nodes when inserting them into inline-only parents.
Editors can mount in an open shadow tree while retaining selection, focus, drag-and-drop, IME composition, and floating-UI behavior.
Fixes Safari IME composition behavior when setting text content on a
TabNode.
lexical 0.4571 changes
Breaking changes 8
Backspace at the start of a non-empty block now merges the previous block’s children into the current block, preserving the current block’s type and format.
Introduces DOMImportExtension as a replacement for importDOM.
Empty inline elements are removed.
The default Markdown import now preserves hard line breaks.
Moving a node between parents now adjusts the current selection to follow the moved node instead of leaving it at the original slot.
Triple-click paragraph selection normalization moved out of LexicalEvents; editors not using rich-text or plain-text registration must register this extension to retain the behavior.
Triple-click selection handling moves to this extension; applications using the former handling may need to update their extension setup.
A runtime guard detects update listeners or transforms that recursively retrigger and throws a descriptive error after a configurable number of nested updates.
New APIs and options 27
HistoryExtension output now includes a ReadonlySignal indicating whether redo is available.
HistoryExtension output now includes a ReadonlySignal indicating whether undo is available.
Inserts a fresh paragraph and places the caret in it when the user clicks below the last block.
Routes text/html pastes through the DOMImportExtension pipeline.
Serializes the current selection, or a caller-provided range, to a Markdown string.
Adds an API to convert the current selection to a Markdown string.
Adds a ListNode method for creating list item nodes, also used during children normalization.
DOM render overrides can be conditionally disabled for an editor.
DOM render overrides can be conditionally disabled for a session.
Adds an experimental composable middleware-style HTML import API with selector-style matchers, optional child schemas, and DOM preprocessing; legacy importDOM continues to work.
Adds a predicate to conditionally skip a render override for a particular editor.
Adds a predicate to conditionally skip a render override for a particular session.
Adds an override surface for DOM rendering as part of the generalized DOMSlot changes.
RichTextExtension supports opt-in format escape triggers.
Is now exported from @lexical/clipboard for use as a peer dependency by custom clipboard handlers.
Exports GetClipboardDataExtension for use by consumers.
The extension output exposes canRedo as a ReadonlySignal<boolean> so toolbar buttons can subscribe without polling historyState.
The extension output exposes canUndo as a ReadonlySignal<boolean> so toolbar buttons can subscribe without polling historyState.
Adds a maxDepth option that bounds the undo stack, evicting older entries FIFO when the limit is exceeded.
Adds a maxDepth option for tuning the history depth.
The plugin supports an optional asynchronous onClose callback.
Provides a list-item factory used by children normalization, letting ListNode subclasses supply a custom ListItemNode without monkey-patching the normalizer.
Exposes the Backspace behavior that merges the previous block’s children into the current block, preserving the current block’s type and format.
Rich-text and plain-text registration now removes empty inline elements; the extension is also available for extension-based setups.
ActionsPlugin can disable PagesExtension in HTML and Markdown modes.
Adds an opt-in signal configuration for controlling format escaping on enter, click, arrow, space, and tab triggers; disabled by default.
Extracts text-align and dir from a DOM element and applies them to an ElementNode; ListItemNode import now uses it for alignment.
Performance 3
Caches the result on the instance.
Adds a children fast path with suffix-incremental cache updates.
Defers DOM Selection property reads.
Behavior and default changes 13
ElementNode now uniformly imports and exports this attribute, allowing subclasses to round-trip indent levels through HTML without overriding importDOM or exportDOM.
ElementNode import and export now support data-lexical-indent.
Child slots can now be expressed for arbitrary DOM containers, and DOM creation, update, export, and slot lookup use the generalized override surface.
Element-shortcut transforms now run on Enter.
Now walks through shadow roots when resolving a node’s reconciled dir attribute, so nested shadow-root elements inherit direction consistently.
Imports the dir attribute.
Clicking after the last block can insert a paragraph.
The onOpenEmbedModalForConfig prop is now optional.
The onClose handler may now return a Promise, allowing asynchronous work before the menu is torn down.
Default Markdown import preserves hard line breaks and handles Unicode whitespace.
Markdown shortcuts now run on Enter and on composition-committed triggers.
$getReconciledDirection now includes the shadow root when determining direction.
May now be null so code blocks without an explicit language round-trip through Markdown without injecting a default language tag.
Fixes and other changes 20
Backspace at the start of a block now preserves the current block.
isBlockDomNode and isInlineDomNode now respect the CSS display style.
Pressing Enter with a block DecoratorNode NodeSelection now inserts a paragraph.
A null Tokenizer.defaultLanguage preserves Markdown fenced-code round trips.
DOM Selection property reads in $updateDOMSelection are deferred.
DOM imports now preserve the dir attribute.
Moving a node between parents now adjusts the current selection to follow the moved node instead of leaving it at the original slot.
Now respects CSS display style when determining whether a DOM node is block-level.
Now respects CSS display style when determining whether a DOM node is inline.
Moving a node between parents now adjusts the current selection to follow the moved node instead of leaving it at the original slot.
Shortcuts typed through IME composition now trigger after composition is committed, rather than only on raw beforeinput.
Prevents crashes on decorator-only elements and restores Shift+Cmd+Arrow selection expansion.
Prevents crashes on decorator-only elements and restores Shift+Cmd+Arrow selection expansion.
Prevents a crash when moving the selection with an arrow key outside a nested table.
Now preserves queued updates and tags through root-element changes.
Now correctly outdents space-indented lines as well as tab-indented lines, respecting the tokenizer’s configured indent width.
Outdenting now works for space-indented code lines.
A null defaultLanguage preserves Markdown fenced-code round trips.
Triple-click selection handling moves to NormalizeTripleClickSelectionExtension.
Lexical detects infinite recursion in update listeners.
lexical 0.4432 changes
Breaking changes 1
$createChildrenArray is now exported from lexical; import it there rather than from @lexical/offset.
Deprecations 4
CodeHighlighterShikiExtension is retained as a deprecated backwards-compatible shim; use CodeShikiExtension.
Using CodeNode without CodeExtension is deprecated; the node is expected to stop working without the extension in a future version.
$createOffsetView is deprecated; use $createChildrenArray from lexical instead.
OffsetView is deprecated because it never worked correctly and has no documentation, tests, or monorepo usage.
New APIs and options 22
AutoLinkExtension accepts an optional punctuation setting to override the default AutoLink boundary characters.
The @lexical/code-prism package now exports CodePrismExtension.
The @lexical/code-shiki package now exports CodeShikiExtension with runtime-toggleable, hot-swappable signal-based configuration.
This priority registers listeners that run most-recently-registered first, ahead of legacy listeners at the same priority.
This priority registers listeners that run most-recently-registered first, ahead of legacy listeners at the same priority.
This priority registers listeners that run most-recently-registered first, ahead of legacy listeners at the same priority.
This priority registers listeners that run most-recently-registered first, ahead of legacy listeners at the same priority.
This priority registers listeners that run most-recently-registered first, ahead of legacy listeners at the same priority.
CreateEditorArgs.dom accepts a partial EditorDOMRenderConfig to override rendering when creating an editor.
$decorateDOM runs after a node is created or updated and its children reconciled, for in-place DOM or attribute tweaks.
domOverride targets node classes, predicates, or the wildcard for DOM rendering overrides; overrides can call $next() to delegate.
The experimental DOMRenderExtension enables composable middleware to override node DOM creation, updating, and export.
EditorDOMRenderConfig parameterizes node rendering and export so they can be overridden through composable middleware.
$generateDOMFromNodes populates a container using the configured render config.
$generateDOMFromRoot populates a container using the configured render config.
$handlePlainTextDrop implements Lexical-aware text drag-and-drop, including cross-editor drags.
$handleRichTextDrop implements Lexical-aware text drag-and-drop, including cross-editor drags and preservation of decorators.
$isLexicalNode is now exported from lexical.
LexicalAutoLinkPlugin accepts an optional punctuation setting to override the default AutoLink boundary characters.
registerAutoLink accepts an optional punctuation setting to override the default AutoLink boundary characters.
Render-context APIs are exposed for reading, updating, and exporting render context values.
SplitAtPointCaretNextOptions gains removeEmptyDestination to control whether an empty destination is replaced entirely.
Behavior and default changes 4
@lexical/extension is now formally stable and no longer marked @experimental.
The NodeState API is now formally stable and no longer marked @experimental.
registerPlainText now wires the shared Lexical-aware drop handler by default.
registerRichText now wires the shared Lexical-aware drop handler by default.
Fixes and other changes 1
The three-Enter code-block escape logic is now handled by a KEY_ENTER_COMMAND listener registered by CodeExtension, fixing blank-line paste escaping code blocks.
lexical 0.4310 changes
New APIs and options 2
Adds CSS classes to collaboration cursor elements, allowing them to be styled.
Adds a module for reading signal values from extension output within React components.
Behavior and default changes 2
Selection style values for properties are now direction-independent.
Infers column header state from position during DOM import.
Fixes and other changes 6
Preserves cursor position when merging adjacent identical links.
Fixes an edge case and provides consistent DecoratorNode behavior inside MarkNode.
Excludes Android WebView from Safari browser detection.
Preserves hard line breaks during import when newlines are preserved.
Nested editors now use asynchronous parent editor delegation when needed, matching pre-0.42.0 legacy behavior.
Fixes merging TextNodes when __state contains a different number of default values.
lexical 0.4229 changes
Breaking changes 6
Markdown handling now enforces CommonMark flanking rules for trailing spaces.
The deprecated ContextMenu was removed; menu rendering was consolidated with the backward-compatible menuRenderFn.
Calling $copyNode now invokes resetOnCopyNodeFrom on the copied node; this affects $copyNode only, not serialization or copy and paste.
At the edge of an ElementNode, deleteWord now behaves like deleteCharacter.
Prism highlighting now lives in this package; migrate Prism highlighting imports from @lexical/code.
Menu rendering was consolidated around this backward-compatible function as deprecated ContextMenu was removed.
Deprecations 1
Prism-related functionality in this package is deprecated; use @lexical/code-prism or @lexical/code-shiki for highlighting.
New APIs and options 6
Inserts a node without splitting containing nodes, including inline elements that can contain the inserted content.
Provides Lexical code functionality without a Prism dependency.
Introduced as part of the extension and playground refactor.
Subclasses can override this method to reset ephemeral state when $copyNode copies a node.
Introduced as part of the extension and playground refactor.
NodeState configurations can mark state for resetting when a node is copied with $copyNode.
Performance 1
Production builds are generated in an ASCII-only format, which may considerably reduce memory usage in some deployment environments.
Behavior and default changes 8
Autolink matching is now enabled when a link is unlinked.
EditableListener callbacks can now return unregister callbacks.
This experimental, incomplete functionality has moved to the playground.
Adjacent LinkNodes with identical attributes are now merged.
Split-like operations now create copies of ListNode and ListItemNode.
Split-like operations now create copies of ListNode and ListItemNode.
RootListener callbacks can now return unregister callbacks.
Markdown import now converts tabs to TabNode.
Tooling 1
Now provides flat configuration and full support for eslint 9 and later.
Fixes and other changes 6
Markdown backslash handling now complies with CommonMark.
Changed from a type alias to an interface.
Inserting consecutive line breaks now preserves selection format.
Now respects CSS scroll-padding when scrolling the editor selection into view.
A single-cell table selection is now prevented after exiting table selection.
Nested table selection handling was improved, including selections crossing into and out of nested tables.
lexical 0.4126 changes
Breaking changes 2
Moving to a different node during composition no longer applies format or style.
The CSS custom property is now read only from the editor root, so CSS or code setting it must target that element.
Deprecations 1
menuRenderFn is now annotated as deprecated.
New APIs and options 3
The checklist extension now offers a focus event option.
A new extension applies format to DecoratorTextNode.
Indentable nodes can now be configured.
Behavior and default changes 8
The caret can now move outside of a code block.
DOM selection is now supported in elements with slots.
Pressing Enter after ``` can now create a code block.
Keyboard shortcuts can now be triggered by physical key code on non-ASCII keyboard layouts.
Nested tables can now be fit when pasted.
ParagraphNode importDOM now supports the legacy HTML align attribute.
Inserted tabs now inherit format and style.
HTML import now supports the scope attribute on th tags.
Fixes and other changes 12
AutoLink no longer links URLs inside code blocks without highlighting.
AutoLinkNode is included in AutoLinkExtension node dependencies and no longer creates extra paragraphs.
The anchor no longer moves when inserting the composition start character.
History now records the character entered during composition.
Formatting is maintained when composition text replaces multiple formatted text nodes.
Nested fenced code blocks now parse and export correctly.
Selected text is now properly deleted after IME input on Safari for macOS.
Nested LinkNode creation is prevented, and blocks are moved outside inline LinkNode elements when inserting a paragraph.
The markdown shortcut link transformer is less greedy when recognizing links.
Ordered list numbering is preserved when a list is split by blocks or paragraphs.
Pasting table rows inside a table now preserves background color.
When the selection is collapsed, $toggleLink removes the whole link.
lexical 0.4016 changes
Breaking changes 3
Moved from @lexical/utils to lexical, changing where developers import it from.
Moved from @lexical/utils to lexical, changing where developers import it from.
Moved from @lexical/utils to lexical, changing where developers import it from.
New APIs and options 1
Exposed the onReposition prop on SelectionAlwaysOnDisplay.
Behavior and default changes 1
Replaced regex-based format matching.
Fixes and other changes 11
Fixed an infinite transform loop in AutoLinkPlugin.
Fixed the cursor disappearing in Firefox when dragging blocks.
Fixed Ctrl+A so it selects all cells in tables with merged cells.
Fixed a selection issue caused by a list transform on linebreak.
Fixed incorrect format tag placement at link boundaries.
Fixed inconsistent multi-cell selection in 2x2 tables.
Fixed formatting being removed on multi-selection after replace.
Fixed toggling links when they have nested children.
Remote cursors are cleared immediately on collaborator refresh.
Fixed a cache coherency bug in RootNode.getTextContent().
Whitespace-only list items are treated as empty when pressing Enter.
lexical 0.399 changes
New APIs and options 2
Commands are available for beforeinput, input, compositionstart, and compositionend events.
An opt-in configuration for nested tables was added, but it does not fix their behavior.
Behavior and default changes 2
Unchanged non-primitive property and state values are no longer rewritten to Yjs in collab v2.
ElementNode JSON now includes textFormat and textStyle only when needed: for non-root elements without direct TextNode children, preserving formatting choices.
Fixes and other changes 5
Table column widths are now ensured to have a length equal to the number of columns.
The caret iterator can now stop at its last descendant.
The first cell's contents are now included in partial backwards table selections.
Text styles are now applied to empty ElementNodes in a selection, such as empty paragraphs in empty table cells.
The typeahead menu no longer closes during IME composition.
lexical 0.3818 changes
Breaking changes 1
Configuration is flattened: pass options such as
defaultThemedirectly instead of nesting them undertokenizer.
New APIs and options 2
Added getServerSnapshot for improved React Server Components compatibility.
LinkExtension now implements mergeConfig.
Behavior and default changes 6
Exceptions in clipboard paste handlers are now logged.
List import now supports Joplin checklists.
Command listener priorities were lowered from CRITICAL to HIGH, allowing applications to override them.
Nodes configuration can be deferred to address circular dependency reasons.
Linked text now supports selective removal.
Static transforms from all superclasses are now applied implicitly, so subclasses do not need to call super when adding a transform.
Fixes and other changes 9
Fixes Markdown formatting when a backslash is before or after a closing backtick.
Fixes cursor position updates on awareness updates in collab v1.
The block cursor is updated when the selection changes.
Fixed the implicit checklist marker export regression.
Elements added and removed between snapshots are skipped.
Lexical selection is retained during updates on unfocused editors.
Moving to the start or end of a line in code blocks now respects right-to-left text direction.
Markdown links with empty strings are no longer automatically removed.
Fixed bugs in normalizeMarkdown when using shouldMergeAdjacentLines.