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 2 days ago
25 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
690 releases · first in 2022
One column per quarter.
Nothing published for this version
[lexical][lexical-playground] Chore: Deprecate KEY_MODIFIER_COMMAND and use KEY_DOWN_COMMAND for playground shortcuts by @etrepum in https://github.co…
Core
Playground
React
Collab
Table
Markdown
Full Changelog: https://github.com/facebook/lexical/compare/v0.30.0...v0.31.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
[Breaking Change][lexical] Bug Fix: Ensure updateEditorSync is always synchronous and use it when triggering listeners by @etrepum in https://github.c…
#7378 changed the internal updateEditorSync implementation to always use the correct active editor when triggering a listener. This only affects how nested editors delegate their events to listeners attached to a parent editor. If you have listeners attached to the parent editor that expect to be called with the context of the nested editor then you'll have to either also attach the listener to the nested editor, or change the behavior to check the editor argument of the command listener to see which editor the command was originally dispatched to.
#7386 changed the behavior of the markdown import's paragraph merging logic to align with GitHub's markdown editor behavior for list and common markdown formatting expectations when shouldPreserveNewlines is true.
#7400 changed the markdown encoder to replace leading or trailing whitespace of formatted strings with the corresponding HTML entities
Core
$getTextNodeOffset invariant to warn in prod (error in __DEV__)Rich Text
Collab
__dir propertyMarkdown
List
registerCheckListLink
Devtools
React
Table
Playground
$setSelection instead of assigning dirty to true directly. by @lilshady in https://github.com/facebook/lexical/pull/7401Full Changelog: https://github.com/facebook/lexical/compare/v0.29.0...v0.30.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
[Breaking Change][lexical] Bug Fix: Only select RootNode on removal of last child if there was an existing selection by @etrepum in https://github.com…
https://github.com/facebook/lexical/pull/7351 : Only select RootNode on removal of last child if there was an existing selection https://github.com/facebook/lexical/pull/7353: Support escaping markdown characters https://github.com/facebook/lexical/pull/7357: Refactor: LexicalNestedComposer add skipEditableListener prop and deprecate initialNodes prop and implicit namespace setting https://github.com/facebook/lexical/pull/7372: Set tableFrozenColumn and tableFrozenRow classes only on the scrollable table wrapper
React: 🆕 https://github.com/facebook/lexical/pull/7357: LexicalNestedComposer add skipEditableListener prop and deprecate initialNodes prop and implicit namespace setting
Table: ✅https://github.com/facebook/lexical/pull/7372: Set tableFrozenColumn and tableFrozenRow classes only on the scrollable table wrapper ✅https://github.com/facebook/lexical/pull/7316: Add fallback selection to InsertTableCommand
Core editor: ✅https://github.com/facebook/lexical/pull/7351: Only select RootNode on removal of last child if there was an existing selection ✅https://github.com/facebook/lexical/pull/7354: Ignore input event from inside decorators
Markdown: 🆕 https://github.com/facebook/lexical/pull/7353: Feature: Support escaping markdown characters
Playground: 🆕 https://github.com/facebook/lexical/pull/7352 : Chore: Improve accessibility of DraggableBlockPlugin add block button ✅https://github.com/facebook/lexical/pull/7334: Table action menu visibility with cell overflow ✅https://github.com/facebook/lexical/pull/7362: Fix equation rendering in Safari 🆕 https://github.com/facebook/lexical/pull/7371: Chore: Update excalidraw to v0.18.0 Doc: ✅https://github.com/facebook/lexical/pull/7365: Update react.md, fix typo
Full Changelog: https://github.com/facebook/lexical/compare/v0.28.0...v0.29.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
[Breaking Change][lexical][lexical-table] Bug Fix: Scrollable TableNode updateDOM fixes and getDOMSlot type refactoring by @etrepum in https://github.…
Ad-hoc minor release with important bug fixes and some enabling features. The most important fix is in #7341 - where under certain conditions nodes may not be updated in the DOM at all (this bug is rarely triggered and has been around for 3+ years).
If you have any $onDelete handlers copied from the playground for KEY_DELETE_COMMAND and KEY_BACKSPACE_COMMAND, you can delete them all now. If you leave them in, it will have similar bugs as prior to this PR.
The default KEY_DELETE_COMMAND and KEY_BACKSPACE_COMMAND handlers now event.preventDefault() and call DELETE_CHARACTER_COMMAND for NodeSelection (in addition to the existing RangeSelection behavior).
The DELETE_CHARACTER_COMMAND handler now handles NodeSelection by calling the new NodeSelection.deleteNodes() method which places a new RangeSelection where the first selected node was (if any, and if it was the current selection) and then removes all of the selected nodes.
This PR moves the incorrectly overridden append methods for RootNode and ListNode and moves it to the ElementNode's primitive splice method. For RootNode this means that the exception you'd get for appending a leaf node to the root will be thrown in all situations when that node is inserted, rather than just append. For ListNode this means that the automatic ListItemNode wrapping applies in all situations when children are inserted into the node, not just append.
Previously $insertNodeToNearestRoot could create empty ElementNode when splitting the current node, now it respects canBeEmpty() and will not split in those cases (e.g. ListNode).
The approach used in #7024 (since v0.26.0) to have a ListItemNode bullet inherit the style of the first text node was too broad, the inline style on the ListItemNode cascades to all of its children. The only way around this is to change the approach.
To retain this feature, you need to add CSS to your theme to specifically style the marker pseudo-element based on these new custom properties. Here's an example from the playground css:
.PlaygroundEditorTheme__listItem::marker {
color: var(--listitem-marker-color);
background-color: var(--listitem-marker-background-color);
font-family: var(--listitem-marker-font-family);
font-size: var(--listitem-marker-font-size);
}
The importDOM implementation for TableCellNode has been corrected to behave as other Lexical roots do with regard to converting <br> tags to LineBreakNode and wrapping runs of top-level inline nodes (including inline decorators) with ParagraphNode. If you have any specific workarounds accounting for the previous behavior, you can remove them. The one difference from other import paths is that a solitary <br> (e.g. <td><br></td>) is converted to an empty ParagraphNode rather than a ParagraphNode containing a LineBreakNode.
If you're using the undocumented internal getDOMSlot API, you may need to change your types. There is now a type parameter for ElementDOMSlot so that the element property can be specialized.
Core:
mutatedNodes to UpdateListener payloadNodeSelection - this allowed a lot of boilerplate code to be deleted, and all of the existing implementations were subtly brokencanBeEmpty() in $splitNodesRootNode transforms lastList:
ListItemNode text style inheritance to CSS custom propertiesTables:
React:
onElementChanged callback to DraggableBlockPluginPlayground:
Utils:
objectKlassEqualsA mutatedNodes property is now present in the UpdateListener payload. This was done to accommodate the use case when you want to have a MutationListener that listens to all nodes (this is useful in combination with NodeState). Note that this property is only calculated when at least one MutationListener is registered (e.g. editor.registerMutationListener(RootNode, () => {}) is sufficient to compute mutatedNodes for all nodes).
NodeSelection.deleteNodes() was added to support the default delete handler
There is now an ordering guarantee that RootNode node transforms are called last, and documentation about the special case that RootNode is always considered intentionally dirty when any other node is dirty
An onElementChanged prop was added to make it possible to implement the "+" button in the playground
Full Changelog: https://github.com/facebook/lexical/compare/v0.27.2...v0.28.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
v0.27.2 is an ad-hoc patch release to address the prismjs CVE (#7313). The way Lexical uses prismjs should not trigger that issue even in previous ver
v0.27.2 is an ad-hoc patch release to address the prismjs CVE (#7313). The way Lexical uses prismjs should not trigger that issue even in previous versions as it doesn't insert user generated HTML with "id" tags or use the autoloader plug-in, but it's good practice to keep up with security updates either way.
Code:
Collab:
Table:
Playground:
Full Changelog: https://github.com/facebook/lexical/compare/v0.27.1...v0.27.2
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.27.1 is an ad-hoc patch release to address the regression introduced in v0.26.0 with LexicalNode.getCommonAncestor which occurs when calling node.g
v0.27.1 is an ad-hoc patch release to address the regression introduced in v0.26.0 with LexicalNode.getCommonAncestor which occurs when calling node.getCommonAncestor(node) when !$isElementNode(node) (#7287).
Core:
Core + List:
Table:
Full Changelog: https://github.com/facebook/lexical/compare/v0.27.0...v0.27.1
Nothing published for this version
[Breaking Changes][lexical] Bug Fix: Address deleteLine regression in #7248 by @etrepum in https://github.com/facebook/lexical/pull/7270
v0.27.0 ad-hoc release to address v0.26.0 regressions.
Core:
Core:
Playground:
Utils:
Collab/Table:
Full Changelog: https://github.com/facebook/lexical/compare/v0.26.0...v0.27.0
Nothing published for this version
[Breaking Change][lexical/react] Chore: Remove deprecated default exports by @kirandash in https://github.com/facebook/lexical/pull/7219
v0.26.0 is a monthly release packed with bug fixes and a major new experimental feature, the NodeState API (#7117).
Core:
#7248 As a follow-up to https://github.com/facebook/lexical/pull/7180 the collapseAtStart logic now continues through both inline and non-inline nodes so long as there are no previous siblings, roots, or shadow roots encountered. This is because nodes such as CollapsibleTitleNode had a collapseAtStart that returns true but contain nodes that are not inline and have a collapseAtStart that returns false (e.g. ParagraphNode).
In order to fix an inconsistency for how nested !isInline elements behave, CollapsibleContainerNode is now a shadowRoot. The CollapsibleContentNode was already a shadowRoot. This is now similar to the situation for tables where both TableNode and TableCellNode are both shadowRoot. The fix here also moved collapseAtStart from CollapsibleTitleNode to CollapsibleContainerNode which makes a bit more sense since the whole container gets collapsed, not just the title. The title is still the only location that you can initiate this collapse from, since it is always the first child.
React:
@lexical/react that had been deprecated since v0.16.0 (June 2024) have been removed:
@lexical/react/LexicalTableOfContents was moved to @lexical/react/LexicalTableOfContentsPluginCore:
Collab:
List:
Mark:
<mark> as an inline elementPlayground:
npm run monorepo:dev command which runs the examples with the version of lexical in the repository (useful for developing examples based on unreleased features, or debugging situations that are difficult to create in the playground)Table:
React:
ListNodeTagType by @DaniGuardiola in https://github.com/facebook/lexical/pull/7228isInline function to TextNode by @mrdivyansh in https://github.com/facebook/lexical/pull/7226Full Changelog: https://github.com/facebook/lexical/compare/v0.25.0...v0.26.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
[Breaking Change][lexical][lexical-link] Bug Fix: Collapse through inline elements in deleteCharacter by @etrepum in https://github.com/facebook/lexic…
v0.25.0 is an ad-hoc release targeted at addressing an input regression with Android Chrome (#7218) , but includes many other fixes (particularly around deleteCharacter) and several new features (such as the NodeCaret API).
Core:
#7180 ElementNode.collapseAtStart(range) would previously only be called on the direct parent of the anchor's node, so the presence of anything like a LinkNode would prevent a ListItemNode from collapsing. Now it will also be called on parents under certain conditions.
#7155 #7204 The heuristic used in RangeSelection.deleteCharacter to handle merging blocks and deleting decorators from a collapsed selection has been refactored for consistency. It now traverses the node tree directly instead of attempting to use browser selection APIs.
Tables:
Core:
Tables:
Code:
React:
Playground:
placeholder examples to ContentEditable by @RobHannay in https://github.com/facebook/lexical/pull/7193Full Changelog: https://github.com/facebook/lexical/compare/v0.24.0...v0.25.0
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 →