NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #4968 most downloaded on npm
This package contains misc utilities for Lexical.
Last release today
17 Sep 2026
Ships on a steady schedule
a new release about every 8 days
Nearly every release is documented
notes for 60 of the last 60 stable releases
1 version withdrawn
withdrawn after publishing
5 years old
684 releases · first in 2022
One column per quarter.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
build(deps): bump webpack-dev-server to >=5.2.4 (CVE-2026-6402) by @xiezhenjia-meta in https://github.com/facebook/lexical/pull/8632
v0.46.0 is a monthly release headlined by two major new experimental capabilities:
editorStateThis release also includes many other fixes and new features across IME/composition, collaboration, markdown round-tripping, lists, code blocks, links, and mobile keyboards. It is also our first release (other than nightlies) to use NPM Trusted Publishing.
Special recognition for this release goes to @mayrang for doing the majority of the work on both of these new features as well as fixing some tricky IME/composition issues 👏 @levensta has also been doing a fantastic job going through the issue backlog, providing valuable feedback on these bleeding edge features, and identifying long-standing edge cases.
lexical — Node traversal methods no longer accept unsafe type parameters (#8661)The zero-argument generics on getParent(OrThrow), getPreviousSibling(s), getNextSibling(s), getChildren, getFirstChild(OrThrow), getLastChild(OrThrow), getChildAtIndex, getFirstDescendant, getLastDescendant, and getDescendantByIndex were implicit unchecked casts — there is no inference site, so any non-base type argument was equivalent to an as cast. Each method is now an overload pair: a documented non-generic signature returning the base type (LexicalNode / ElementNode | null), plus the old generic signature marked @deprecated. Code that leaned on contextual-type inference no longer type-checks:
// Before: compiled (unsound). After: type error.
const node: ParagraphNode | null = $getRoot().getFirstChild();
// Port directly with an explicit cast (no behavior change):
const node = $getRoot().getFirstChild() as ParagraphNode | null;
// Or, better, narrow with a guard:
const node = $getRoot().getFirstChild();
if ($isParagraphNode(node)) { /* node: ParagraphNode */ }
Existing getFirstChild<ParagraphNode>()-style calls still compile but are now deprecated and will be removed in a future release. This is a types-only change with no runtime impact.
lexical — $getNearestNodeFromDOMNode(rootElement) now returns RootNode (#8588)The "selection captured outside of Lexical" mechanism is generalized beyond DecoratorNode subtrees: setDOMUnmanaged(dom, {captureSelection: true}) now marks any subtree (e.g. a DOMRenderExtension override or a getDOMSlot widget) as selection-captured, and isDOMCapturingSelection(dom) walks ancestors so a descendant <input> reports as captured. As part of this, the root element now carries a __lexicalKey_* stash, so $getNodeFromDOM / $getNearestNodeFromDOMNode resolve the root element to the RootNode instead of null. Two call sites become more correct (drop-on-root in clipboard, table-selection→range conversion), but external callers that relied on $getNearestNodeFromDOMNode(rootElement) returning null must update. The internal-only $isSelectionCapturedInDecorator was removed.
lexical — insertNodes preserves a leading linebreak; managed <br>s are now tagged (#8615)RangeSelection.insertNodes now preserves the first LineBreakNode when inserting inline content ahead of a block element, instead of silently dropping it. Separately, the reconciler-inserted "managed" line breaks (the otherwise-invisible <br>s Lexical adds so the caret can land in empty lines) are now identifiable in the DOM as <br data-lexical-managed-linebreak="true"> — and, on iOS Safari, an analogous <img data-lexical-managed-linebreak="true" …> in some cases. DOM/HTML snapshot test expectations may need to ignore or expect this attribute. Closes #3980.
@lexical/html and node extensions — DOMImportExtension rules now register implicitly (#8662) (experimental)The experimental DOM-import pipeline no longer requires you to list a per-package import extension. Each node-providing extension (RichTextExtension, ListExtension, LinkExtension, TableExtension, CodeExtension) now registers its own import rules, and the standalone RichTextImportExtension / ListImportExtension / LinkImportExtension / TableImportExtension / CodeImportExtension / HorizontalRuleImportExtension become deprecated aliases that may be removed as early as v0.47.0. Rules stay inert unless HTML is routed through ClipboardDOMImportExtension or $generateNodesFromDOMViaExtension; the legacy importDOM paste path is unchanged. If you had not adopted these v0.45.0 extensions yet, there is no breaking change.
lexical / @lexical/yjs / @lexical/clipboard / @lexical/html — Named slots (#8603) (experimental)All slot machinery is opt-in and gated (an editor latches _slotsUsed on the first $setSlot), so editors that never use slots take identical code paths to before. Two changes are observable regardless:
syncLexicalUpdateToYjsV2__EXPERIMENTAL takes a new dirtyLeaves parameter, inserted between dirtyElements and normalizedNodes (a slot host's values surface as dirty leaves).NodeSelection containing an ElementNode now includes that element's children on copy/export ($getHtmlContent / $generateJSONFromSelectedNodes). The previous behavior serialized a childless shell, making cut of an element NodeSelection silently lossy; partial RangeSelections keep per-child slicing and excludeFromCopy children remain excluded.@lexical/link / @lexical/list / @lexical/react — Removed exports deprecated since v0.32.1 (#8704)Exports marked @deprecated in v0.32.1 (2025-06-04, >12 months ago) with no Meta-internal consumers are removed:
@lexical/link: toggleLink → use $toggleLink@lexical/list: insertList / removeList → use $insertList / $removeList (from an update or command listener)@lexical/react: the ContentEditable Props type alias → use ContentEditablePropsNote: lexical's $nodesOfType is intentionally un-deprecated (it still has many consumers). The remaining v0.32.1 deprecations that still have internal consumers (KEY_MODIFIER_COMMAND, $wrapNodes, the @lexical/table row/column helpers, etc.) are left for a follow-up.
lexical — editor.read(mode, fn) and EditorReadMode (#8702)read gains an optional first argument: 'force-commit' (the default; flushes pending updates first — the previous one-argument behavior), 'pending' (reads the pending state without flushing — the old editor.readPending, now removed), and 'latest' (reads the committed state without flushing, equivalent to editor.getEditorState().read(fn, {editor})). EditorReadMode is exported. readPending only shipped after v0.45.0, so its removal is not considered a breaking change.
lexical — DOM shadow root support (#8694)An editor can now mount inside an open shadow tree without losing selection, focus, drag-and-drop, IME composition, or floating-UI behavior. Reads go through platform APIs — Selection.getComposedRanges, Selection.direction, ShadowRoot.activeElement, Document.caretPositionFromPoint(x, y, {shadowRoots}) — and nine new helpers ship from lexical; the light-DOM code paths are unchanged. Follow-ups #8708 (insert nodes at the block cursor inside a shadow root) and #8740 (ignore beforeinput/input in captured decorators, fixing Firefox 152) complete the surface.
lexical — onWarn editor hook (#8644)CreateEditorArgs gains an optional onWarn?: ErrorHandler (stored as _onWarn, defaulting to console.warn), mirroring onError. The infinite-update-loop guard's recoverable warning now routes through it (wired end-to-end in #8658), so embedders that bridge reporting to their own telemetry no longer lose this signal to each user's browser console.
lexical — $config() accessor-based nominal typing (#8645)An additive extension of the $config() protocol: abstract base classes can declare configuration shared with their subclasses under a Symbol.for(<ClassName>) key (resolved by getStaticNodeConfig), and accessor-based nominal typing lets subclasses opt into stricter $config() checks. No existing node class is changed.
@lexical/history — Cut/paste get their own undo entry (#8649)Any update tagged PASTE_TAG or CUT_TAG is now classified as an OTHER change inside @lexical/history, which keeps it from merging into the preceding keystrokes and keeps following keystrokes from merging into it. Undoing a short paste (or an iOS autocorrect/prediction) or a cut no longer also undoes the text you typed immediately before it.
@lexical/extension — SelectBlockExtension (#8532)Overrides SELECT_ALL_COMMAND so the first invocation selects the nearest block element and the second selects the entire document; a selection already spanning multiple blocks expands straight to the document, and select-all is a no-op when everything is already selected. Includes an opt-in cascadeSelection option for nested editors (image captions, etc.) and enables PreventSelectAllExtension by default to keep keydown from leaking out of input/textarea elements. (Also introduced editor.read('pending', …) via the now-generalized #8702.)
@lexical/yjs / @lexical/react — Collaborative cursors via the CSS Custom Highlight API (#8550)Remote collaborators' selections are now painted with the widely-supported CSS Custom Highlight API; the error-prone absolutely-positioned overlay remains only as a fallback. The remote caret is still rendered as a positioned element. Closes #4457, #5837.
@lexical/utils — dedupeSelectionRects (#8709)A new exported helper that drops zero-area rects and any rect that contains another (with 1px tolerance) from Range.getClientRects(), fixing the duplicate/over-bright and spurious extra-wide fake-selection rects WebKit produces on some blocks. It is wired into positionNodeOnRange, so every fake-selection consumer (markSelection, selectionAlwaysOnDisplay, the extension) gets clean rects. Addresses #7106, #7492.
@lexical/code-core — escapeWithArrows (#8393)CodeIndentExtension gains an escapeWithArrows option (default false): when a code block is the terminal node and the caret is at the end of its text, pressing the arrow keys creates a new paragraph and moves the caret into it. New $onEscapeDown / $onEscapeUp helpers back it in @lexical/utils. Closes #7912, #4685, #5968.
@lexical/react — Self-contained LexicalErrorBoundary (#8720)LexicalErrorBoundary no longer wraps react-error-boundary (the dependency is dropped) and gains an optional fallback prop — omit it for the default message, or pass fallback={null} to render nothing. Its public type is unchanged, so it remains usable as the ErrorBoundary prop of RichTextPlugin / PlainTextPlugin.
lexical):$getNearestNodeFromDOMNode(rootElement) resolves to RootNode; generalized captured selection via setDOMUnmanaged({captureSelection})insertNodes; tag managed <br> with data-lexical-managed-linebreakeditor.read(mode, fn) overload + EditorReadMode (replaces readPending)onWarn editor hook (#8658 routes the recursion guard through it end-to-end)$config() accessor-based nominal typingTabNode.setTextContent for Safari IME compositionCOMPOSITION_END_TAG from the Firefox onInput defer branchbeforeinput/input in captured decorators (Firefox 152)devInvariant$assumeEditor warns via devInvariant instead of throwing in prodklass.prototype null check in getStaticNodeConfiginheritsLoose-safe helper for class-inheritance loopstokenizeRawText / $generateNodesFromRawTextgetStaticNodeConfigT[] over Array<T>, modernized Flow stubs, dropped deprecated traversal type params in testseditorState$generateHtmlFromNodes self-establishes active-editor scope (back-compat for #8519)SelectBlockExtensionescapeWithArrows: create a paragraph around a terminal code block with the arrow keysLinkNode wrap on copy in Firefox/SafariDecoratorNode on Backspace at the start of a top-level listMarkNode method return types to boolean (restores subclass overrides)$handleTableSelectionChangeCommand@lexical/yjs) / Dragon:@lexical/dragon: handle makeChanges messages and the listener-registration racededupeSelectionRects — clean up WebKit fake-selection rectsgetScrollParent to @lexical/utilsLexicalErrorBoundary (drops react-error-boundary) with an optional fallback prop.js.flow files; 📝 #8714 API doc coverage of @lexical/react exportspreventDefault() in dragover for HTML5 DnD complianceAutocompleteDictionary)¶, ↵, →, ·), toggled from SettingsPageBreakNode as <hr> so Safari fires beforeinput after paste/esm/ proof of concept@flaky tags)ActionsPluginEACCES in Windows CI browser testseditor.getEditorState().read(...) to editor.read('latest', ...)AGENTS.md / CLAUDE.md)tmp dependency; #8647 replace the node-state-style example with the dev-examples versionFull Changelog: https://github.com/facebook/lexical/compare/v0.45.0...v0.46.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
🧹 #8401 #8404 #8405 #8406 #8408 #8409 #8415 #8540 Dependency vulnerability fixes (protobufjs, dompurify, postcss, astro, eslint, immutable, path-to-re…
v0.45.0 is a monthly release with several breaking changes around selection and reconcile semantics, a major new experimental DOMImportExtension API for composable HTML import that replaces importDOM, a generalized DOMSlot and DOM render override surface, new HistoryExtension ergonomics (canUndo/canRedo signals, maxDepth), notable reconciler/selection performance work, and a wide range of bug fixes across IME, mobile keyboards, list/code/table editing, and markdown round-tripping.
lexical — Shadow root inclusion in $getReconciledDirection (#8479)$getReconciledDirection now walks through shadow roots when resolving the reconciled dir attribute on a node, so nested ShadowRoot-style elements (e.g. tables) inherit direction consistently with regular elements. Callers that relied on direction inheritance stopping at shadow roots will need to update.
lexical / @lexical/rich-text — Backspace at block start preserves the current block (#8493)Pressing Backspace at the start of a non-empty block previously merged the current block into the previous block, which discarded the current block's type/format. The new behavior merges the previous block's children into the current block instead, preserving the current block's type (heading, list item, quote, etc.). A new $mergeBlockBackward helper on RangeSelection is exposed for custom command handlers that want the same behavior.
lexical — Selection adjustment in removeFromParent callers (#8501)LexicalNode.replace, insertBefore, insertAfter, and related callers that move a node between parents now correctly adjust the current selection to follow the moved node instead of leaving the selection pointing at the (now empty) original slot. This may change selection state observed by transforms or update listeners that previously relied on the stale offsets.
@lexical/markdown — Apply markdown shortcuts on composition-committed triggers (#8503)Markdown shortcuts (e.g. *, _, ~) typed via IME composition now trigger after the composition is committed, not just on raw beforeinput. This fixes shortcuts being silently dropped during Japanese / Korean / Chinese input but may also fire shortcuts in some flows that previously didn't.
@lexical/extension / @lexical/rich-text / @lexical/plain-text — NormalizeInlineElementsExtension (#8497)registerRichText and registerPlainText now register a transform that removes empty inline elements (e.g. LinkNode, formatted TextNode wrappers with no children) instead of leaving them in the tree. The transform is also exported as NormalizeInlineElementsExtension from @lexical/extension for use with extension-based setups. Editors that intentionally kept empty inline wrappers will need to disable the extension or override the transform. See Included Extensions.
lexical / @lexical/extension / @lexical/rich-text / @lexical/plain-text — NormalizeTripleClickSelectionExtension (#8520)The "triple-click selects the whole paragraph including the trailing newline" normalization has moved out of LexicalEvents and into a new NormalizeTripleClickSelectionExtension registered by both rich-text and plain-text. The core LexicalEditor no longer performs this normalization on its own, so editors that bypass registerRichText / registerPlainText (or the equivalent extensions) need to register the extension explicitly to keep the previous behavior. See Included Extensions.
lexical / @lexical/html / @lexical/selection / @lexical/utils / @lexical/playground — Generalized DOMSlot and DOMRenderExtension override surface (#8519)DOMSlot is now generalized so child slots can be expressed for arbitrary DOM containers (not just the direct child element), and $createDOM, $updateDOM, $exportDOM, $getDOMSlot etc. all flow through the new override surface. The previously-exported AutocompleteNode in the playground has been replaced by a VisibleLineBreakExtension that demonstrates the new override surface, and markSelection in @lexical/utils has been rewritten on top of the generalized slot API. Custom nodes that override getDOMSlot to return a non-element wrapper now have a real way to express that. See the DOMRenderExtension docs.
@lexical/html — DOMImportExtension (experimental) (#8528)A new DOMImportExtension replaces the legacy node-class importDOM static method with a composable middleware-style API. Rules declare a CSS-selector-style matcher, an optional schema for child handling, and a DOMImportFn that builds Lexical nodes from the matching DOM. Many helpers ship alongside it: $distributeInlineWrapper, ImportSession, DOMPreprocessFn for source-specific cleanup (Word, VS Code, etc.), and full TypeScript types for rules, captures, and contexts. A new dev-examples/dom-import showcase wires it up to a Word/VS Code paste flow. The legacy importDOM continues to work; new code can opt in to DOMImportExtension for richer composition and explicit ordering. The companion ClipboardDOMImportExtension (in @lexical/clipboard) routes text/html pastes through the new pipeline. See the DOMImportExtension guide and the "Migrating from importDOM" section.
@lexical/html / @lexical/playground — Conditional DOM render overrides (#8575)domOverride now supports disabledForEditor and disabledForSession predicates so render overrides can be conditionally skipped on a per-editor or per-session basis (e.g. only apply during export, or only when a feature flag is on). Useful when one extension provides multiple overrides whose applicability depends on context that isn't known at registration time. See the DOMRenderExtension docs.
lexical — ElementNode import/export of data-lexical-indent (#8536)ElementNode now uniformly imports and exports the data-lexical-indent attribute so any subclass round-trips its indent level through HTML without having to override exportDOM / importDOM (fixes the long-standing #7729 regression around indented headings/paragraphs).
lexical — Infinite recursion detection in update listeners (#8542)Update listeners and update transforms that re-trigger themselves are now caught by a runtime guard that throws a descriptive error after a configurable number of nested updates, instead of hanging the tab. See Updates and Listeners.
@lexical/history — canUndo / canRedo ReadonlySignals (#8465)HistoryExtension's output now exposes canUndo and canRedo as ReadonlySignal<boolean>s so toolbar buttons can subscribe directly without polling historyState or duplicating the priority/state bookkeeping. See Extension Signals.
@lexical/history — maxDepth option (#8537)HistoryExtension accepts a new maxDepth option that bounds the undo stack. Older entries are evicted FIFO when the depth is exceeded. See the new "Tuning HistoryExtension for memory and long sessions" docs.
@lexical/markdown — $convertSelectionToMarkdownString (#8395)Counterpart to $convertToMarkdownString that serializes only the current selection (or any caller-provided range) to a markdown string, useful for "copy as markdown" toolbar actions and for selection-scoped AI prompts.
lexical / @lexical/list — $setFormatFromDOM (#8460)A new $setFormatFromDOM helper extracts text-align / dir from a DOM element and applies it to an ElementNode. ListItemNode.importDOM now uses it to correctly import alignment for list items pasted from external sources.
@lexical/list — ListNode.createListItemNode (#8427)ListNode exposes a createListItemNode factory that is now used by children-normalization, so ListNode subclasses can supply a custom ListItemNode subclass without monkey-patching the normalizer.
@lexical/rich-text — escapeFormatTriggers on RichTextExtension (#8383)RichTextExtension now accepts an escapeFormatTriggers config (a ReadonlySignal<EscapeFormatTriggerConfig>) that opts text-format escape behavior in/out per trigger (enter, click, arrow, space, tab). With it enabled, typing at the boundary of a formatted text node "escapes" the active format (bold, italic, code, etc.), matching the typing experience in Google Docs / Notion. Disabled by default. See Included Extensions.
@lexical/extension / @lexical/playground — ClickAfterLastBlockExtension (#8549)New ClickAfterLastBlockExtension inserts a fresh paragraph when the user clicks below the last block (and places the caret in it), so single-block editors and short documents don't strand the user with no easy way to start a new line.
@lexical/code-prism / @lexical/code-shiki — null Tokenizer.defaultLanguage (#8553)Tokenizer.defaultLanguage may now be null to indicate that code blocks without an explicit language should round-trip through markdown without injecting a default language tag (e.g. ```javascript). Preserves CommonMark's "no fence info" form on export.
@lexical/code-core / @lexical/code-shiki / @lexical/code-prism — Outdent space-indented code lines (#8445)Shift+Tab in a code block now correctly outdents space-indented lines (not just tab-indented), respecting the tokenizer's configured indent width.
@lexical/react — Optional async onClose for LexicalTypeaheadMenuPlugin (#8489)LexicalTypeaheadMenuPlugin's onClose may now return a Promise, useful for handlers that need to await network or animation work before tearing down the menu.
@lexical/clipboard — GetClipboardDataExtension export (#8431)GetClipboardDataExtension is now exported from @lexical/clipboard for use as a peer dependency from custom clipboard handlers.
@lexical/website — Server-rendered "Copy page" Markdown button (#8570)Every docs page now has a server-rendered "Copy page as Markdown" button (and a matching ?raw URL) so AI assistants and humans can grab the raw markdown without scraping the rendered HTML.
Core:
$getReconciledDirectionLexicalNode callers move a node out of its parentDOMSlot and add DOMRenderExtension override surface; markSelection rewritten on topNormalizeTripleClickSelectionExtensionElementNode import/export of data-lexical-indent$updateDOMSelectionRangeSelection.isBackward() on the instanceNodeMap and reconciler keyToDOMMap$reconcileChildren<br> reconciledir attribute in importDOMdisplay style in isBlockDomNode / isInlineDomNode--lexical-indent-base-value via CSS var() instead of pre-computing in JSsetRootElementdeleteContentBackward with targetRange$setBlocksTypeDecoratorNode$reconcileChildren fast path during full reconcileMOVE_TO_END / MOVE_TO_START crash on decorator-only elementsMOVE_TO_END / MOVE_TO_STARTHTML / DOM:
DOMImportExtension — composable replacement for importDOM with rule-based matchers and DOM preprocessingdisabledForEditor / disabledForSession predicates on domOverrideCode:
null Tokenizer.defaultLanguage to preserve markdown ``` round-trip<br> elements in pasted codeClipboard:
GetClipboardDataExtensionExtension:
NormalizeInlineElementsExtension (also wired into rich/plain text)NormalizeTripleClickSelectionExtensionClickAfterLastBlockExtension$canIndentHistory:
canUndo / canRedo ReadonlySignals on HistoryExtensionmaxDepth option for bounding the undo stackLink / List:
$setFormatFromDOM; ListItemNode imports alignment from DOMListNode.createListItemNode factory for subclassesMarkdown:
*/_/~)$convertSelectionToMarkdownString APIReact:
onClose for LexicalTypeaheadMenuPlugineditorState.read() in markSelectionExtensionComponent support for output components with required propsonOpenEmbedModalForConfig prop optional in LexicalAutoEmbedPluginRich Text / Plain Text:
escapeFormatTriggers on RichTextExtensionDecoratorNode NodeSelectionTable:
pointerdown handler when root element is set after registerYjs:
TextNodes in collab v2RenderSnapshot comment typoPlayground:
FloatingLinkEditor correctly for multi-line / decorator-only links and near the editor's bottom edge<details> with loose body contentPagesExtension to be disabled by ActionsPlugin (HTML & markdown mode)font-size for h2EquationNode click → NodeSelection; empty-input Backspace removesWebsite / Examples:
editorState null vs undefined and empty-state pitfallNodeState in $config JSON serializationLexicalNodeReplacement and withKlass@lexical/react plugin docsdev-node-state-style into examples/node-state-styleskipLibCheck in react-rich for lib-types regression coverage (#7093)update-team-datadocusaurus-plugin-internaldocs-fb presetembed=1 from non-iframe StackBlitz links/docs/error page from undefined processInfrastructure:
browserslistArrowDown workaround in Tables.spec.mjswindows-2022playwright install-deps instead of apt-get@playwright/test to ^1.60.0release.js to release.mjscreateListItemNode method to the ListNode and use it for children normalization by @levensta in https://github.com/facebook/lexical/pull/8427$setFormatFromDOM function and use it to import alignment for ListItem by @levensta in https://github.com/facebook/lexical/pull/8460onOpenEmbedModalForConfig prop optional in LexicalAutoEmbedPlugin by @levensta in https://github.com/facebook/lexical/pull/8485$canIndent by @levensta in https://github.com/facebook/lexical/pull/8510$setBlocksType by @flavorjones in https://github.com/facebook/lexical/pull/8517Full Changelog: https://github.com/facebook/lexical/compare/v0.44.0...v0.45.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
🧹 #8324 Override yaml to >=1.10.3 to fix CVE-2026-33532
v0.44.0 is a monthly release with a few minor breaking changes (deprecations), a notable new experimental DOMRenderExtension API for overriding DOM create/update/export, easier to use priority levels for registering commands, a pagination demonstration and convenient html import/export in the playground, better drag and drop support, automatic inline of CSS for HTML import, consistent CSP-safe style updates, and a wide range of bug fixes and other new features.
@lexical/offset OffsetView (#8350)OffsetView / $createOffsetView never worked correctly, has no documentation, no tests, and no usage in the monorepo. It has been deprecated. The only function still in use, $createChildrenArray, is now exported from lexical itself — import it from lexical rather than @lexical/offset going forward.
CodeExtension (#8360)The "press Enter three times to exit a CodeNode" logic has moved from CodeNode.insertNewAfter to a KEY_ENTER_COMMAND listener registered by CodeExtension. This fixes paste-with-blank-lines incorrectly escaping the code block. Using CodeNode without CodeExtension is now deprecated — a backwards-compatible shim with a dev-mode warning is in place, but the node is expected to stop working without CodeExtension in a future version.
lexical / @lexical/html — Extensible DOM rendering and export (experimental) (#8353, #8368)A new DOMRenderExtension (in @lexical/html) and EditorDOMRenderConfig (in lexical) parameterize $createDOM, $updateDOM, $exportDOM, $getDOMSlot, $shouldInclude, and $shouldExclude so that node rendering and export can be overridden via composable middleware. Use domOverride(nodes, config) to target one or more node classes, predicates, or '*' (wildcard), and call $next() from inside an override to delegate to the underlying implementation.
A new $decorateDOM(nextNode, prevNode, dom, editor) hook runs after a node is created/updated and after its children have been reconciled, intended for in-place attribute or DOM tweaks. Override ordering is a well-defined topological sort: wildcards highest, then predicates, then class hierarchy (subclass before superclass), with extension dependency order and registration order as tiebreakers.
Render-context APIs are also exposed: $withRenderContext, $getRenderContextValue, contextValue, contextUpdater, RenderContextRoot, RenderContextExport. New traversal helpers $generateDOMFromNodes and $generateDOMFromRoot populate a container using the configured render config. CreateEditorArgs.dom accepts a Partial<EditorDOMRenderConfig> to override rendering at editor creation. $isLexicalNode is also exported from lexical.
lexical — COMMAND_PRIORITY_BEFORE_* priorities (#8375)Five new command priorities — COMMAND_PRIORITY_BEFORE_EDITOR, _BEFORE_LOW, _BEFORE_NORMAL, _BEFORE_HIGH, _BEFORE_CRITICAL — register listeners that run most-recently-registered first, in front of the existing first-registered-first listeners at the same priority. Ordering is: highest priority first, then all BEFORE_* listeners (LIFO), then legacy listeners (FIFO). The new priorities are almost always what you want for new code; legacy priorities are unchanged so this is purely additive. See the new "Priorities and ordering" docs.
@lexical/code-prism — CodePrismExtension & @lexical/code-shiki — CodeShikiExtension (#8346)Both packages now export proper extensions (CodePrismExtension, CodeShikiExtension) with {disabled, tokenizer} signal-based configuration that can be toggled and hot-swapped at runtime. The legacy CodeHighlighterShikiExtension is kept as a deprecated backwards-compatible shim.
@lexical/link / @lexical/react — Custom AutoLink punctuation (#8378)AutoLinkExtension, registerAutoLink, and LexicalAutoLinkPlugin now accept an optional punctuation setting to override the default boundary characters (e.g. to allow colon-delimited matches without breaking URLs that contain colons).
@lexical/utils — removeEmptyDestination for split-at-caret (#8384)SplitAtPointCaretNextOptions (used by $insertNodeToNearestRootAtCaret and $splitAtPointCaretNext) gains a removeEmptyDestination option for finer control over whether an empty destination is replaced entirely.
@lexical/clipboard — Shared drop handlers (#8373)New $handleRichTextDrop and $handlePlainTextDrop helpers implement Lexical-aware text drag-and-drop, including same-block drags, cross-TextNode and cross-block drops, DecoratorNode preservation, and cross-editor drags. registerRichText and registerPlainText now wire these by default.
@experimental) (#8354)@lexical/extension (since v0.36.1, Sep 2025) and the NodeState API in lexical (since v0.26.0, Feb 2025) are now formally stable.
@lexical/offset OffsetView / $createOffsetView (use $createChildrenArray from lexical) (#8350)@lexical/text $findTextIntersectionFromCharacters — broken, untested, undocumented (#8364)CodeHighlighterShikiExtension / CodeHighlighterShikiConfig (use CodeShikiExtension) (#8346)CodeNode without CodeExtension (#8360)Core:
OffsetView; export $createChildrenArray from lexicalEditorDOMRenderConfig, DOMRenderExtension, domOverride, $decorateDOM, render context, $generateDOMFromNodes, $generateDOMFromRoot, $isLexicalNode, CreateEditorArgs.domCOMMAND_PRIORITY_BEFORE_* priorities for last-registered-called-first ordering@experimental from Extension and NodeState APIsClipboard / Rich Text / Plain Text:
DecoratorNodes and formatting are preserved across drops; cross-editor drags work even with two Lexical versions on the same pageCode:
KEY_ENTER_COMMAND listener in CodeExtension; fixes blank-line paste escaping the code blockCodePrismExtension (@lexical/code-prism) and CodeShikiExtension (@lexical/code-shiki)shiki to ^4.0.2Extension:
react type dependency from DecoratorTextNodeLexicalExtensionEditorComposer no longer disposes the editor on unmount; lifetime is the caller's responsibility (fixes nested/caption editors after remount)HTML / Table:
<style> tags during HTML import (fixes paste from Excel, Outlook, etc.)<li> during HTML export, eliminating duplicate ordered-list numberingLink:
List:
ListItemNode always has a ListNode parent (orphans are merged or floated to root)pointerup<li> on HTML exportMarkdown:
\d+\. ) inside bullet/check list item exports to fix double-escape on round-tripPlayground:
PagesExtension with PageNode, PageContentNode, PageSetupNode for paginated documents and print-friendly output$generateHtmlFromNodes / $generateNodesFromDOM); HTML view formatted with prettierPageBreak, Twitter, YouTube, Figma, TabFocus, Collapsible, SpecialText, code-highlight) and remove the dead LinkPlugin and StickyPlugin filesNodeContextMenuPlugin falls back to the root node when the click target has no Lexical node, instead of showing an empty menu@floating-ui/react for FloatingLinkEditorPlugin positioning; correctly handles all viewport boundaries and Firefox focusNode.parentElement quirksReact:
editorRef is null in LexicalEditorRefPluginyjs as an optional peer dependency for Yarn PnP compatibilityLexicalExtensionEditorComposerNodeContextMenuPluginText:
$findTextIntersectionFromCharactersUtils:
$insertNodeToNearestRootAtCaret edge cases; add removeEmptyDestination to SplitAtPointCaretNextOptionsRefactor (CSP-safe styles):
cssText / setAttribute('style', …) writes with property-based style updates across lexical, @lexical/code-core, @lexical/list, @lexical/table, @lexical/yjs, and the playgroundWebsite:
tsconfig.json for lexical-website so type errors are actually surfaced in CIInfrastructure:
$config in AGENTS.mdyaml to >=1.10.3 to fix CVE-2026-33532simple-git dependency vulnerabilityfollow-redirects dependency vulnerabilityCOMMAND_PRIORITY_BEFORE_* priorities for last-registered-called-first order by @etrepum in https://github.com/facebook/lexical/pull/8375Full Changelog: https://github.com/facebook/lexical/compare/v0.43.0...v0.44.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
v0.43.0 is a monthly release with a minor breaking change, new features, and a number of bug fixes across selection, tables, markdown, and extensions.…
v0.43.0 is a monthly release with a minor breaking change, new features, and a number of bug fixes across selection, tables, markdown, and extensions. Notable highlights include a new useExtensionSignalValue hook, and CSS theme options for Yjs collaboration cursors.
Outside of the release artifact, we've refreshed the lexical.dev website thanks to @m-santanna (and inspired by design mockups from @ixahmedxi). Importantly this refresh includes a set of modern examples (examples/website-* and examples/agent-example) that are embedded on the front page and showcase current best practices.
@lexical/react nested editors now use asynchronous parent editor delegation when needed to match pre-0.42.0 legacy behavior.
@lexical/react - useExtensionSignalValue #8286A new @lexical/react/useExtensionSignalValue module is available for reading signal values from extension output within React components
Core:
IS_SAFARI browser detectionTextNodes when __state contains a different number of default values$insertNodes with $insertNodeIntoLeaf for consistent DecoratorNode behavior inside MarkNodeCode:
skipTransforms in CodeHighlighterPrism and CodeHighlighterShikiExtension:
@lexical/react/useExtensionSignalValue module for reading signals from ReactExamples:
Headless:
window.happyDOM.close() to ensure proper cleanupLink:
Markdown:
Playground:
isExactShortcutMatch for Dvorak keyboard compatibilitySelection:
$getSelectionStyleValueForProperty direction-independentTable:
Utils:
$insertNodeIntoLeaf edge case; update @preact/signals-core, hermes, and flow dependenciesYjs:
Infrastructure:
^7.3.2flow-bin to 0.306.0 and add incompatible-variance workaroundusing)Full Changelog: https://github.com/facebook/lexical/compare/v0.42.0...v0.43.0
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →