facebook/lexical
 Watch   
 Star   
 Fork   
2026-04-27 22:29:34
lexical

v0.44.0

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.

Breaking Changes

Deprecation of @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.

Code block escape logic moved to 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.

New APIs

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.

lexicalCOMMAND_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-prismCodePrismExtension & @lexical/code-shikiCodeShikiExtension (#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/utilsremoveEmptyDestination 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.

Stable APIs (no longer @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.

Deprecations

  • @lexical/offset OffsetView / $createOffsetView (use $createChildrenArray from lexical) (#8350)
  • @lexical/text $findTextIntersectionFromCharacters — broken, untested, undocumented (#8364)
  • CodeHighlighterShikiExtension / CodeHighlighterShikiConfig (use CodeShikiExtension) (#8346)
  • Using CodeNode without CodeExtension (#8360)

Highlights

Core:

  • ⚠️ #8350 Deprecate OffsetView; export $createChildrenArray from lexical
  • 🆕 #8353 #8368 EditorDOMRenderConfig, DOMRenderExtension, domOverride, $decorateDOM, render context, $generateDOMFromNodes, $generateDOMFromRoot, $isLexicalNode, CreateEditorArgs.dom
  • 🆕 #8375 COMMAND_PRIORITY_BEFORE_* priorities for last-registered-called-first ordering
  • 🧹 #8354 Remove @experimental from Extension and NodeState APIs
  • ✅ #8356 Workaround for synchronous Firefox focus edge case where deferred callbacks were silently discarded
  • ✅ #8349 Resolve Firefox arrow-key navigation skipping over collapsible content
  • ✅ #8361 Fall back to non-shifted key matching for Option+number shortcuts on macOS

Clipboard / Rich Text / Plain Text:

  • ✅ #8373 Drag-and-drop within the same block now correctly moves the dragged text; DecoratorNodes and formatting are preserved across drops; cross-editor drags work even with two Lexical versions on the same page

Code:

  • ⚠️ #8360 Move three-Enter code-block escape logic to a KEY_ENTER_COMMAND listener in CodeExtension; fixes blank-line paste escaping the code block
  • 🆕 #8346 Add CodePrismExtension (@lexical/code-prism) and CodeShikiExtension (@lexical/code-shiki)
  • 🧹 #8330 Upgrade shiki to ^4.0.2

Extension:

  • ✅ #8328 Remove JSX/react type dependency from DecoratorTextNode
  • ✅ #8377 LexicalExtensionEditorComposer no longer disposes the editor on unmount; lifetime is the caller's responsibility (fixes nested/caption editors after remount)

HTML / Table:

  • 🆕 #8326 Inline CSS from <style> tags during HTML import (fixes paste from Excel, Outlook, etc.)
  • ✅ #8313 Merge nested lists into the parent <li> during HTML export, eliminating duplicate ordered-list numbering

Link:

  • 🆕 #8378 Allow custom punctuation for AutoLink boundaries

List:

  • ✅ #8382 Ensure ListItemNode always has a ListNode parent (orphans are merged or floated to root)
  • ✅ #8390 Toggle checklist items on mobile tap (iOS Safari / Android Chrome) via pointerup
  • ✅ #8313 Merge nested lists into parent <li> on HTML export

Markdown:

  • ✅ #8332 Replace negative lookbehind assertions for Safari < 16.4 compatibility
  • ✅ #8365 Add an undo history entry for markdown shortcut transforms so undo no longer also undoes the triggering keystroke
  • ✅ #8311 Escape ordered-list pattern (\d+\. ) inside bullet/check list item exports to fix double-escape on round-trip
  • ✅ #8381 Code spans take precedence over inline formatting in shortcut transforms (CommonMark behavior)

Playground:

  • 🆕 #8322 New PagesExtension with PageNode, PageContentNode, PageSetupNode for paginated documents and print-friendly output
  • 🆕 #8323 Animations for collapsible section expand/collapse and arrow rotation
  • 🆕 #8379 #8386 "Convert to HTML" toolbar button (round-trips through $generateHtmlFromNodes / $generateNodesFromDOM); HTML view formatted with prettier
  • 🆕 #8346 Migrate eight playground plugins to extensions (PageBreak, Twitter, YouTube, Figma, TabFocus, Collapsible, SpecialText, code-highlight) and remove the dead LinkPlugin and StickyPlugin files
  • ✅ #8385 NodeContextMenuPlugin falls back to the root node when the click target has no Lexical node, instead of showing an empty menu
  • ✅ #8388 Use @floating-ui/react for FloatingLinkEditorPlugin positioning; correctly handles all viewport boundaries and Firefox focusNode.parentElement quirks
  • ✅ #8392 Show floating link editor for single-character links (right-bias adjacent-link lookup)

React:

  • ✅ #8329 Prevent error when editorRef is null in LexicalEditorRefPlugin
  • ✅ #8366 Add yjs as an optional peer dependency for Yarn PnP compatibility
  • ✅ #8377 Don't auto-dispose editor from LexicalExtensionEditorComposer
  • ✅ #8385 Root-node fallback in NodeContextMenuPlugin

Text:

  • 🧹 #8364 Add deprecation notice to $findTextIntersectionFromCharacters

Utils:

  • ✅ #8384 Clean up and test $insertNodeToNearestRootAtCaret edge cases; add removeEmptyDestination to SplitAtPointCaretNextOptions

Refactor (CSP-safe styles):

  • 🧹 #8372 Replace runtime cssText / setAttribute('style', …) writes with property-based style updates across lexical, @lexical/code-core, @lexical/list, @lexical/table, @lexical/yjs, and the playground

Website:

  • 🆕 #8316 Add more examples to the demos gallery and statically capture screenshots with Playwright (replaces the third-party screenshot service)
  • ✅ #8369 Fix tailwindcss docusaurus config regression (sync, not async)
  • ✅ #8371 Add a dedicated tsconfig.json for lexical-website so type errors are actually surfaced in CI

Infrastructure:

  • 🧹 #8341 Encourage agents to use extensions and $config in AGENTS.md
  • 🧹 #8355 Refactor CommonJS scripts to ESM modules
  • 🧹 #8357 Cache build + Playwright before running e2e tests
  • 🧹 #8324 Override yaml to >=1.10.3 to fix CVE-2026-33532
  • 🧹 #8358 Address simple-git dependency vulnerability
  • 🧹 #8380 Address follow-redirects dependency vulnerability
  • 🧹 #8334 Remove example/fixture lockfiles from git to reduce Dependabot noise
  • 🧹 #8336 #8347 Update stale dev dependencies to resolve Dependabot alerts

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.43.0...v0.44.0

2026-04-10 00:31:06
lexical

v0.43.0

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.

Breaking Changes

Asynchronous parent editor delegation #8308

@lexical/react nested editors now use asynchronous parent editor delegation when needed to match pre-0.42.0 legacy behavior.

New APIs

@lexical/react - useExtensionSignalValue #8286

A new @lexical/react/useExtensionSignalValue module is available for reading signal values from extension output within React components

Highlights

Core:

  • ⚠️ #8308 Use asynchronous parent editor delegation when needed in nested editors
  • ✅ #8267 Exclude Android WebView from IS_SAFARI browser detection
  • ✅ #8273 Fix merging TextNodes when __state contains a different number of default values
  • ✅ #8266 Replace $insertNodes with $insertNodeIntoLeaf for consistent DecoratorNode behavior inside MarkNode

Code:

  • ✅ #8254 Remove usage of skipTransforms in CodeHighlighterPrism and CodeHighlighterShiki

Extension:

  • 🆕 #8286 Add @lexical/react/useExtensionSignalValue module for reading signals from React

Examples:

  • 🆕 #8281 Add a new agent example using a local LLM (Transformers.js / in-browser)
  • 🆕 #8258 Add additional website examples

Headless:

  • ✅ #8274 Use window.happyDOM.close() to ensure proper cleanup

Link:

  • ✅ #8309 Preserve cursor position when merging adjacent identical links

Markdown:

  • ✅ #8265 Preserve hard line breaks during import when newlines are preserved

Playground:

  • ✅ #8260 Use isExactShortcutMatch for Dvorak keyboard compatibility

Selection:

  • ✅ #8261 Make $getSelectionStyleValueForProperty direction-independent

Table:

  • ✅ #8259 Infer column header state from position during DOM import

Utils:

  • ✅ #8276 Fix $insertNodeIntoLeaf edge case; update @preact/signals-core, hermes, and flow dependencies

Yjs:

  • 🆕 #8271 Add CSS classes to collaboration cursor elements

Infrastructure:

  • 🧹 #8287 Upgrade ESLint 8 → ESLint 10 with flat configuration
  • 🧹 #8307 Upgrade Vite to ^7.3.2
  • 🧹 #8248 Update GitHub CI workflows and run with Node 24
  • 🧹 #8253 Update flow-bin to 0.306.0 and add incompatible-variance workaround
  • 🧹 #8277 #8315 Bump Flow and replace legacy Flow syntax with modern equivalents
  • 🧹 #8243 Update unit tests with extensions to use explicit resource management (using)

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.42.0...v0.43.0

2026-03-20 04:19:17
lexical

v0.42.0

v0.42.0 is a monthly release with a huge number of fixes and features from a lot of new contributors. The most notable fixes are related to tables, links, extensions, and markdown. @lexical/eslint-plugin is now fully compatible with eslint 9+. The production builds are also now generated in an ascii-only format which may considerably reduce memory usage in some deployment environments.

Breaking Changes

Prism highlighting extracted from @lexical/code #8198

Prism highlighting now lives in @lexical/code-prism and the Prism related functionality in @lexical/code is now deprecated. Transitionally, there is a @lexical/code-core package which has the implementation of Lexical's code functionality without a Prism dependency.

Experimental hasFitNestedTables has been moved to the playground #8210

Due to its experimental nature and incomplete implementation, the in-progress hasFitNestedTables functionality has been moved to the playground

New APIs

lexical - $copyNode + LexicalNode.resetOnCopyNodeFrom & NodeState resetOnCopyNode

After $copyNode is used it now calls copiedNode.resetOnCopyNodeFrom(originalNode) which will reset every NodeState that has resetOnCopyNode: true in its configuration. Subclasses can override this method to reset other "ephemeral" state such as whether a ListNodeItem is checked or not.

Note that this does not influence serialization or copy and paste operations, it only affects calls to $copyNode.

@lexical/utils - $insertNodeIntoLeaf

The current behavior RangeSelection.insertNodes can split an inline ElementNode (e.g. a LinkNode) when inserting content, even if that content is also inline and could be a child of the given node. $insertNodeIntoLeaf is now provided to insert a node without splitting any containing nodes.

Highlights

Core:

  • 🧹 #8190 Change EditorThemeClasses from type to interface
  • ✅ #8218 Respect CSS scroll-padding in scrollIntoViewIfNeeded
  • ✅ #8220 deleteWord now behaves the same as deleteCharacter when at the edge of an ElementNode
  • 🆕 #8221 resetOnCopyNode configuration to NodeState and LexicalNode.resetOnCopyNodeFrom hook
  • 🆕 #8219 LexicalEditor RootListener and EditableListener can return unregister callbacks
  • ✅ #8222 Consecutive Linebreak insertion now preserves selection format

Code:

  • ⚠️ #8198 Extract Prism highlighting code to @lexical/code-prism and add @lexical/code-core to provide a dependency that does not include Prism. @lexical/code remains backwards compatible with Prism included, but you should migrate to using highlighting from @lexical/code-shiki or @lexical/code-prism.

Devtools:

  • ✅ #8230 Clean up strict mode useLexicalCommandsLog behavior

Extension:

  • 🆕 #8202 LexicalExtensionEditorComposer, NestedEditorExtension, and fixed SharedHistoryExtension with playground refactor

Markdown:

  • ✅ #8170 Enforce CommonMark flanking rules for trailing spaces
  • ✅ #8192 Update backslash handling to comply with CommonMark
  • ✅ #8211 Convert tabs to TabNode on import

Link:

  • ✅ #8165 Enable autolink matching when unlinked
  • 🆕 #8236 Merge adjacent LinkNodes with identical attributes

Eslint Plugin:

  • 🧹 #8227 Add flat configuration and full eslint 9+ support for @lexical/eslint-plugin

List:

  • 🆕 #8213 Create copies of ListNode/ListItemNode in split-like operations

React:

  • 🧹#8199 Remove deprecated ContextMenu, consolidate menu rendering with backward-compatible menuRenderFn

Table:

  • ✅ #8187 Use monolithic listener for SELECTION_CHANGE_COMMAND and deselection handler
  • ✅ #8193 Improve nested table selection by using monolithic pointer event handling
  • ✅ #8195 Prevent single-cell table selection after exiting table selection
  • ✅ #8200 Call $handleTableSelectionChangeCommand once instead of per-table
  • 🧹 #8215 Add test for mouse leaving browser window during table selection
  • ⚠️ #8210 hasFitNestedTables functionality moved to the playground
  • ✅ #8234 Handle table selections crossing into/out of nested tables

Utils:

  • 🆕 #8206 Add $insertNodeIntoLeaf with example usage in playground DateTimeNode

Misc:

  • 🧹 #8229 #8235 #8226 #8241 Add and fix afterCloneFrom and accessor implementations

Infrastructure

  • 🧹 #8239 Upgrade rollup packages and configure terser for ascii_only output

Playground:

  • ✅ #8186 Add fallback for dimensionless images to prevent collapse
  • 🧹 #8188 Remove legacy events mode
  • 🆕 #8183 Nested tables resize themselves with hasFitNestedTables: true
  • ✅ #8214 Use inline style for LayoutContainerNode import
  • ✅ #8228 Fix cursor position after EquationNode
  • ✅ #8224 make clear formatting work on multiple paragraphs

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.41.0...v0.42.0

2026-02-25 12:03:20
lexical

v0.41.0

v0.41.0 is a monthly release with a huge number of fixes and features from a lot of new contributors. The most notable fixes are related to IME, non-ascii keyboard layouts, and markdown.

Breaking Changes

--lexical-indent-base-value CSS moved to root element #8132

The --lexical-indent-base-value CSS custom property is now only read from the root element of the editor, so any CSS or code to set this value must target that rather than an indented element in the document. This allows the indent to be computed while the document is being rendered without layout thrashing.

Highlights

Core

  • ⚠️ #8132 Breaking Change: Fix --lexical-indent-base-value CSS variable override
  • ✅ #8111 Prevent layout thrashing when setting element indent for no indent case
  • 🆕 #8115 Support legacy 'align' attribute in ParagraphNode importDOM
  • ✅ #8121 IME: Do not move anchor when inserting composition start char
  • ✅ #8142 IME: Fix history not recording composing character
  • ✅ #8148 IME: Do not apply format and style when moving to a different node in composition
  • ✅ #8154 IME: Fix selected text not properly deleted after IME input on Safari (macOS)
  • ✅ #8162 IME: Maintain format when multiple formatted text nodes are replaced with composition text
  • ✅ #8159 Support DOM selection in elements with slots Code
  • 🆕 #7918 Allow moving caret outside of code block
  • 🆕 #8155 Trigger keyboard shortcuts by physical key code with non-ascii keyboard layouts

Extension

  • 🆕 #8114 Implement DecoratorTextExtension applying format to DecoratorTextNode

Rich Text

  • 🆕 #8122 Support configuration of indentable nodes
  • ✅ #8152 Inherit format and style when inserting tab

Link

  • ✅ #8123 Prevent AutoLink from linking URLs inside code blocks without highlighting
  • ✅ #8127 Prevent AutoLinkNode from creating extra paragraphs
  • ✅ #8137 Add AutoLinkNode to AutoLinkExtension node dependencies
  • ✅ #8138 $toggleLink should remove the whole link when selection is collapsed
  • ✅ #8164 Prevent creation of nested LinkNode
  • ✅ #8158 Transform to move blocks outside of LinkNode List
  • 🆕 #8092 Preserve ordered list numbering when split by blocks or paragraphs
  • ✅ #8118 Remove empty parent node in nested list
  • 🆕 #8105 Add focus event option for the checklist extension

Table

  • 🆕 #8097 Implement "fit nested tables" for nested table pasting
  • 🆕 #8094 Support 'scope' attribute in HTML import for th tags
  • ✅ #8131 Preserve Background Color when pasting table rows inside table

Markdown

  • ✅ #8116 Fix nested fenced code blocks parsing and export
  • 🆕 #8140 Support Enter key after ``` to create code block
  • ✅ #8161 Prevent markdown shortcut link transformer from being too greedy

Playground

  • 🆕 #8063 Rearrange table columns
  • ✅ #8134 Increase toolbar z-index to prevent content overlap
  • ✅ #8149 Code block formatting in unintended adjacent lines

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.40.0...v0.41.0

2026-02-02 12:53:46
lexical

v0.40.0

v0.40.0 is a monthly release primarily focusing on bug fixes and infrastructure such as the move from npm to pnpm.

Some very notable changes include:

  • Some major fixes and refactoring to markdown parsing #8093 #8085
  • Several of the most common utilities were moved from @lexical/utils to lexical (mergeRegister, addClassNames, removeClassNames) #8106
  • A cache coherency bug in RootNode.getTextContent() was fixed #8099

Highlights

Monorepo:

  • 🧹 #8035 Chore: Transition from npm to pnpm (also #8045 #8048 #8050 #8051 #8054 #8106)

Link:

  • ✅ #8070 Fix: Fix infinite transform loop in AutoLinkPlugin
  • ✅ #8078 Fix: Toggle links with nested children

List:

  • ✅ #8049 Fix: fix selection issue from list transform on linebreak
  • ✅ #8068 Fix: Treat whitespace-only list items as empty when pressing Enter

Markdown:

  • ✅ #8085 Fix: Fix incorrect format tag placement at link boundaries
  • ✅ #8093 Fix: Replace regex-based format matching

Core:

  • ✅ #8069 Fix: format removed on multi selection after replace
  • ✅ #8099 Fix: Refactor RootNode.__cachedText computation for coherency

Table:

  • ✅ #8076 Fix: Fix Ctrl+A to select all cells in table with merged cells
  • ✅ #8081 Fix: Fix inconsistent multi-cell selection in 2x2 tables
  • 🧹 #8088 Chore: Fix test for nested table pasting

Utils:

  • 🧹 #8106 Chore: Move functions mergeRegister, addClassNames, removeClassNames to lexical package

React:

  • ✅ #8062 Fix: Clear remote cursor immediately on collaborator refresh
  • ✅ #8065 Fix: Fix cursor disappearing in Firefox when dragging blocks
  • ✅ #8071 Chore: Expose onReposition prop on SelectionAlwaysOnDisplay

Playground:

  • 🆕 #8043 Feature: Color table resize handle
  • 🆕 #8042 Feature: Draggable block handle gliding effect
  • ✅ #8052 Fix: Draggable handle and dropdown CSS zoom fix
  • 🆕 #8057 Feature: New Table Hover Actions Plugin
  • 🆕 #8060 Feature: Column Sort for Basic Table
  • 🆕 #8066 Feature: Add button shows the component picker
  • ✅ #8087 Fix: Prevent code block line wrapping to keep line number

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.39.0...v0.40.0

2025-12-11 03:49:28
lexical

v0.39.0

v0.39.0 is a monthly release primarily focusing on bug fixes

Breaking Changes

JSON serialization for ElementNode only includes textFormat and textStyle when necessary #7971

Previously the derived properties textFormat and textStyle would always be serialized to JSON if not set to the default values. These should only be useful when the ElementNode does not currently have any TextNode children, to preserve formatting choices, and will be recomputed when reconciled. Now they are only reconciled when they are determined to be useful (in an ElementNode with no direct TextNode children that is not a root or shadow root).

Highlights

Code:

  • ✅ #7970 Fix: Scope highlight cache by editor

Core:

  • ✅ #7971 Fix: Only serialize ElementNode textFormat and textStyle when necessary
  • 🆕 #7964 Feature: Add commands for beforeinput, input, compositionstart/end events
  • ✅ #7978 Fix: $dfsCaretIterator should be able to stop at its last descendant

Selection:

  • ✅ #8003 Fix: Text styles are now applied to empty ElementNodes in a selection (typically the empty paragraphs contained in empty table cells)

Extension:

  • ✅ #7961 Fix: Defer node class references to potentially work around webpack issues

Table:

  • 🧪 #7983 Experiment: add config for opting in to nested tables (note that this does not fix their behavior)
  • ✅ #7986 Fix: Ensure colWidths has length equal to number of columns
  • ✅ #7998 Fix: Include first cell contents in partial backwards table selection

React:

  • ✅ #7987 Prevent typeahead menu from closing during IME composition

Collab:

  • ✅ #7990 Fix: Don't rewrite unchanged non-primitive property/state values to yjs in collab v2

Playground:

  • 🆕 #8002 Feature: Shadows when table is scrollable
  • ✅ #8015 Fix: Show draggable block target line when dragging images

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.38.2...v0.39.0

2025-10-31 08:22:26
lexical

v0.38.2

v0.38.2 is a patch release to fix a regression in yjs cursor position awareness (#7960). It also includes another fix for a Markdown issue.

Highlights

React:

  • ✅ #7960 Fix: update cursor positions on awareness update in collab v1

Markdown:

  • ✅ #7958 Fix markdown formatting when a backslash is before or after a closing backtick

What's Changed

Full Changelog: https://github.com/facebook/lexical/compare/v0.38.1...v0.38.2

2025-10-28 04:07:36
lexical

v0.38.1

v0.38.1 is an monthly release with a lot of fixes and a few potentially breaking changes (this is a re-publish of v0.38.0, which had problems during initial npm publish).

Breaking Changes

#7926 Static transforms from superclasses are always applied

Before $config there was a limited amount of "automatic" re-use of the static transform by subclasses, because class inheritance also inherits static methods, so you get the implementation of whatever static transform method was in the superclass if it wasn't overridden.

Now the application of these static transforms (whether by method or $config) is implicit. There is no need to call super if adding an additional transform. The implementation walks up the inheritance tree by $config extends or Object.getPrototypeOf and will register all transforms it finds.

#7936 Extension configuration for CodeHighlighterShikiExtension has been flattened

If you are using CodeHighlighterShikiExtension the configuration has changed.

Before:

configExtension(CodeHighlighterShikiExtension, {tokenizer: {...ShikiTokenizer, defaultTheme: })

After:

configExtension(CodeHighlighterShikiExtension, {defaultTheme: })

#7933 LexicalTableSelectionHelpers listener priorities lowered to HIGH from CRITICAL

This is unlikely to break most applications but the priority of these command listeners has been lowered to allow them to be overridden.

Highlights

Core:

  • ✅ #7926 Apply static transform and $config $transform from all superclasses (fixes ListNode/ListItemNode subclassing)
  • ✅ #7941 Retain lexical selection during updates on unfocused editors
  • ✅ #7947 Update block cursor if selection has changed

Extension:

  • 🆕 #7930 Allow nodes config to be deferred for circular dependency reasons
  • ⚠️ #7936 Implement mergeConfig for LinkExtension and flatten config for CodeHighlighterShikiExtension

List:

  • 🆕 #7946 importDOM support for joplin checklists

Table:

  • ⚠️ #7933 Lower table handler command priority

Clipboard:

  • ✅ #7942 Log exceptions in clipboard paste handlers

Link:

  • 🆕 #7944 Enable Selective Removal Within Linked Text

React:

  • ✅ #7935 Add getServerSnapshot for improved RSC compatibility

Collab v2:

  • ✅ #7922 Skip elements that were added and removed between snapshots

Code:

  • ✅ #7921 Respect RTL when moving to line start/end in code blocks

Markdown:

  • ✅ #7812 Fix bugs in normalizeMarkdown when using shouldMergeAdjacentLines
  • ✅ #7923 Prevent markdown links with empty strings from being automatically removed
  • ✅ #7928 Fix implicit checklist marker export regression

Playground:

  • ✅ #7920 Fix image caption overflow

Examples:

  • 🧹 #7939 Remove workaround from svelte example

Documentation:

  • 🧹 #7931 Update docusaurus and contributing docs

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.37.0...v0.38.1

2025-10-11 22:55:22
lexical

v0.37.0

v0.37.0 is an ad-hoc release, primarily to update the happy-dom dependency to address a CVE (#7909 - lexical's usage of this package was not susceptible) but also includes several bug fixes. This was marked as a minor release because it includes an experimental collab v2 implementation which is not yet ready for use (see #7616 #7903)

Highlights

Core:

  • #7900 ✅ Fix $cloneWithProperties so that it doesn't throw an exception when used in read-only mode
  • #7904 🆕 Add new (internal) ephemeral node concept for situations where a cloned node is intentionally decoupled from the editor state for mutations that will only have a local effect

Examples:

  • 🆕 #7879 New sveltekit ssr example demonstrating the use of @lexical/headless/dom

React:

  • ✅ #7899 LexicalMenu guard against undefined option when list shrinks

Collab:

  • 🆕 #7616 #7903 #7907 #7908 Initial implementation of collab v2

List

  • 🆕 #7892 Keep list marker for markdown round-trip

Rich Text:

  • ✅ #7902 Fix up/down arrows for node selection

Clipboard/Playground:

  • ✅ #7900 ImageNode caption support for exportDOM and importDOM
  • ✅ #7906 Export ParagraphNode as div role="paragraph" when it contains block DOM (such as the <figure> from ImageNode captions)

Headless

  • 🧹 #7909 Update to happy-dom v20 to address CVE reports (lexical's usage was not susceptible)

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.36.2...v0.37.0

2025-10-01 10:14:42
lexical

v0.36.2

v0.36.2 is a bug fix release, primarily to fix a problem with the @lexical/headless package.json that prevented the new @lexical/headless/dom from being used as designed. It also includes several improvements and bug fixes such as the new SKIP_SELECTION_FOCUS_TAG.

Highlights

Core:

  • 🆕 #7804 New SKIP_SELECTION_FOCUS_TAG to allow the update to set the DOM selection but not automatically ensure that the root element is focused
  • 🧹 #7870 devInvariant should warn in prod even if not in codes.json (only relevant for unreleased versions, npm releases, even nightly ones, have an up to date codes.json)

Clipboard:

  • ✅ #7880 Copying from a collapsed selection no longer updates the clipboard (consistent with the browser's default behavior and other applications)

Markdown:

  • ✅ #7890 Ensure First Match is Used in importTextMatchTransformer Table:
  • ✅ #7864 Handle accessing table selection following table deletion Playground:
  • ✅ #7804 Improve focus management in toolbar DOM
  • ✅ #7847 Table add-row button no longer hides horizontal scroll

React:

  • ✅ #7843 Ensure selection listeners cleaned up from original owner document

HTML:

  • 🆕 #7859 $generateNodesFromDOM now accepts any ParentNode (not just Document) as input

Headless:

  • 🆕 #7873 #7859 @lexical/headless/dom should be usable now

Docs:

  • 🆕 #7830 Add example for how to bootstrap collab ydoc on the server
  • 🆕 #7893 Export DOMConversion* types so that they are in the docs
  • 🧹 #7881 Update to docusaurus v3.9.1

What's Changed

New Contributors

Full Changelog: https://github.com/facebook/lexical/compare/v0.36.1...v0.36.2