v0.47.0
nestjs/nestv0.47.0Jul 9, 2026by etrepum
AI Summary
A major monthly release for Lexical featuring two new experimental packages, React 18 as the new baseline, and extensive improvements to IME/composition handling, selection navigation, and markdown/table functionality.
Key Highlights
- New experimental packages: @lexical/mdast and @lexical/a11y
- React 18 is now the minimum supported version
- New Find and Replace and Ruby annotation playground features
- Extensive IME, composition, and mobile input fixes
Breaking Changes
- React 17 support dropped - minimum version is now React 18
- DOM element preservation changed for segmented TextNode during composition
New Features
- New @lexical/mdast package for markdown parsing
- New @lexical/a11y package for accessibility helpers
- New table utilities: $setTableRowIsHeader, $setTableColumnIsHeader
- New DOM event helpers: registerEventListener / registerEventListeners
- Find and Replace feature in playground
- Ruby annotation node with floating editor
Full Release Notes
v0.47.0 is a monthly release with a lot of bug fixes, particularly related to IME and composition, and is headlined by two new experimental packages: - [`@lexical/mdast`](https://lexical.dev/docs/api/modules/lexical_mdast) ([#8794](https://github.com/facebook/lexical/pull/8794)) — a [micromark](https://github.com/micromark/micromark)/[mdast](https://github.com/syntax-tree/mdast)-based alternative to `@lexical/markdown`. Parsing, serialization, and markdown shortcuts all go through the same parser used by `remark`, so CommonMark + GFM compliance comes for free and there is no second grammar to keep in sync. The original syntax of each construct is preserved on the nodes, so re-serializing produces minimally different Markdown. `@lexical/markdown` remains the supported default for production apps. See the new [Markdown with `@lexical/mdast` guide](https://lexical.dev/docs/serialization/markdown-mdast). - [`@lexical/a11y`](https://lexical.dev/docs/api/modules/lexical_a11y) ([#8591](https://github.com/facebook/lexical/pull/8591)) — framework-agnostic accessibility helpers (ARIA live regions, focus management, roving tab index, focus trap) usable from React, Svelte, Vue, Solid, or vanilla DOM, with React wrappers shipping from `@lexical/react`. The playground adopts them as part of a WCAG AA reference pass, and the keyboard contracts Lexical follows are documented in the new [Keyboard Accessibility guide](https://lexical.dev/docs/concepts/keyboard-accessibility). Beyond the headliners: React 18 is now the baseline (see Breaking Changes), the playground gains Find and Replace and a Ruby annotation node with a floating editor, tables learn to spread pasted TSV across cells and get row/column header utilities, and there is a long list of IME/composition, selection, and navigation fixes. Special recognition once again goes to @mayrang who has been plowing through IME, accessibility, and other input related issues as well as the really cool new Find and Replace and Ruby Annotations playground features. ## Breaking Changes ### `@lexical/react` / `@lexical/devtools-core` — React 17 support dropped ([#8782](https://github.com/facebook/lexical/pull/8782)) React 18 is now the minimum supported version; the `react` / `react-dom` peerDependencies require `>=18`, and React 17 compatibility code paths were removed. If you are already on React 18 or 19, no changes are required. ### `lexical` — DOM element preserved when composing on a segmented TextNode ([#8784](https://github.com/facebook/lexical/pull/8784)) Starting IME composition in the middle of a segmented `TextNode` (e.g. a mention) previously replaced the node — destroying its DOM element and breaking the browser's composition tracking (caret flashing and styling bleed on Chrome). The node now temporarily switches to `normal` mode for the duration of composition, keeping the same node key and DOM element, and is cleaned up when composition ends. Subclass transforms or method overrides that assume a segmented node is always in segmented mode must account for this transient state — see the updated [`TextNode.setMode()` documentation](https://lexical.dev/docs/api/classes/lexical.TextNode#setmode). ## New APIs - [`lexical`](https://lexical.dev/docs/api/modules/lexical) — `$getDocument()` returns the owner document of the active editor (correct inside a [Shadow DOM or iframe](https://lexical.dev/docs/concepts/shadow-dom)), falling back to the global document when there is no active editor; a new `@lexical/eslint-plugin` rule enforces its use over the `document` global ([#8788](https://github.com/facebook/lexical/pull/8788), [#8813](https://github.com/facebook/lexical/pull/8813)) - [`lexical`](https://lexical.dev/docs/api/modules/lexical) — `registerEventListener` / `registerEventListeners`, type-safe `addEventListener` helpers that return cleanup functions, now used throughout the codebase — see the updated [Working with DOM Events guide](https://lexical.dev/docs/concepts/dom-events) ([#8767](https://github.com/facebook/lexical/pull/8767)) - [`lexical`](https://lexical.dev/docs/api/modules/lexical) — `SET_TEXT_FORMAT_COMMAND` sets (rather than toggles) the selection's text format (see [Commands](https://lexical.dev/docs/concepts/commands)); the same PR fixes `formatText` toggle direction ([#8807](https://github.com/facebook/lexical/pull/8807)) - [`@lexical/markdown`](https://lexical.dev/docs/api/modules/lexical_markdown) — `$generateNodesFromMarkdownString` parses a markdown string into Lexical nodes without inserting them into the document or modifying the selection ([#8789](https://github.com/facebook/lexical/pull/8789)) - [`@lexical/table`](https://lexical.dev/docs/api/modules/lexical_table) — `$setTableRowIsHeader` and `$setTableColumnIsHeader` utilities ([#8815](https://github.com/facebook/lexical/pull/8815)); `$insertTableRowAtNode` and `$insertTableColumnAtNode` are now exported ([#8791](https://github.com/facebook/lexical/pull/8791)) ## Notable Fixes **IME, composition & mobile** - Prevent text duplication on iOS Safari when formatting during composition ([#8755](https://github.com/facebook/lexical/pull/8755)) - Skip ZWSP insertion for format mismatch on Android Chrome ([#8769](https://github.com/facebook/lexical/pull/8769)); deduplicate speech-to-text insertion on Android Chrome ([#8759](https://github.com/facebook/lexical/pull/8759)) - Event module globals moved into per-editor `InputState` ([#8809](https://github.com/facebook/lexical/pull/8809)); refactored IME composition test infrastructure with browser-level coverage ([#8793](https://github.com/facebook/lexical/pull/8793)) **Selection & navigation** - ArrowUp/Down no longer skip block decorators ([#8775](https://github.com/facebook/lexical/pull/8775)); `deleteLine` no longer removes adjacent block decorators ([#8744](https://github.com/facebook/lexical/pull/8744)) - Keep selection inside single-child inline elements ([#8772](https://github.com/facebook/lexical/pull/8772)); fix navigation across unmergeable TextNode boundaries in inline-grid containers ([#8797](https://github.com/facebook/lexical/pull/8797)) - `$setBlocksType` properly handles block-end focus in backward selections ([#8753](https://github.com/facebook/lexical/pull/8753)); `insertNodes` re-resolves a detached firstBlock ([#8764](https://github.com/facebook/lexical/pull/8764)) - Place the block cursor between decorators and shadow roots ([#8758](https://github.com/facebook/lexical/pull/8758)); clean up the trailing shadow root after select-all delete ([#8751](https://github.com/facebook/lexical/pull/8751)) - `deleteCharacter` no longer overwrites the X11 PRIMARY selection via `Selection.modify` ([#8774](https://github.com/facebook/lexical/pull/8774)) - Defer `onUpdate` callbacks during nested commits ([#8672](https://github.com/facebook/lexical/pull/8672)) **Markdown, code & tables** - Fence-like lines inside a code block stay content ([#8734](https://github.com/facebook/lexical/pull/8734)); prevent formatting on `TabNode` inside code blocks ([#8752](https://github.com/facebook/lexical/pull/8752)) - Pasted TSV text spreads across table cells ([#8780](https://github.com/facebook/lexical/pull/8780)) **Playground & website** - Find and Replace ([#8779](https://github.com/facebook/lexical/pull/8779)) and Ruby annotation node with floating editor ([#8741](https://github.com/facebook/lexical/pull/8741)) - Support Unicode URLs in the autolink matcher ([#8787](https://github.com/facebook/lexical/pull/8787)); restore RTL checkbox position in checklists ([#8783](https://github.com/facebook/lexical/pull/8783)); forced-colors (high contrast) icon fixes ([#8781](https://github.com/facebook/lexical/pull/8781), [#8773](https://github.com/facebook/lexical/pull/8773)) - Rewritten [testing guide](https://lexical.dev/docs/testing) on the website ([#8811](https://github.com/facebook/lexical/pull/8811)) ## What's Changed - [lexical][lexical-rich-text][lexical-selection] Bug Fix: Fix navigation across unmergeable TextNode boundaries in inline-grid containers ([#8797](https://github.com/facebook/lexical/pull/8797)) by @mayrang - [lexical][lexical-rich-text] Bug Fix: Fix formatText toggle direction and add SET_TEXT_FORMAT_COMMAND ([#8807](https://github.com/facebook/lexical/pull/8807)) by @mayrang - [scripts] Bug Fix: Let npm prompt for OTP when publishing bootstrap stubs ([#8820](https://github.com/facebook/lexical/pull/8820)) by @etrepum - [lexical-playground] Bug Fix: Clear inline font-size when converting to heading ([#8800](https://github.com/facebook/lexical/pull/8800)) by @mayrang - [lexical-table][lexical-playground] Feature: $setTableRowIsHeader and $setTableColumnIsHeader utilities ([#8815](https://github.com/facebook/lexical/pull/8815)) by @mayrang - [lexical-website] Documentation Update: Rewrite testing guide ([#8811](https://github.com/facebook/lexical/pull/8811)) by @mayrang - [lexical-mdast][lexical-rich-text] Feature: @lexical/mdast, a micromark/mdast-based alternative to @lexical/markdown ([#8794](https://github.com/facebook/lexical/pull/8794)) by @etrepum - Make dependency-check resilient to transient registry errors ([#8818](https://github.com/facebook/lexical/pull/8818)) by @zurfyx - [lexical] Refactor: Move event module globals into per-editor InputState ([#8809](https://github.com/facebook/lexical/pull/8809)) by @mayrang - [lexical] Bug Fix: $getDocument() should fall back to the global document when there is no active editor ([#8813](https://github.com/facebook/lexical/pull/8813)) by @potatowagon - [lexical-playground] Bug Fix: Keep cell background color modal open on first click ([#8806](https://github.com/facebook/lexical/pull/8806)) by @sahiee-dev - [lexical-playground] Bug Fix: Use consistent default maxWidth for markdown-imported images ([#8810](https://github.com/facebook/lexical/pull/8810)) by @mayrang - [*][lexical-devtools][lexical-playground] Chore: Update flow, hermes, and babel packages to latest ([#8795](https://github.com/facebook/lexical/pull/8795)) by @etrepum - Add a 7-day pnpm minimumReleaseAge to match the Dependabot cooldown ([#8808](https://github.com/facebook/lexical/pull/8808)) by @zurfyx - [lexical] Chore: Fix tmp package dependency vulnerability ([#8802](https://github.com/facebook/lexical/pull/8802)) by @vijayojha89 - [lexical] Chore: Add missing Flow type declarations ([#8799](https://github.com/facebook/lexical/pull/8799)) by @mayrang - [lexical-markdown] Feature: Add $generateNodesFromMarkdownString ([#8789](https://github.com/facebook/lexical/pull/8789)) by @mayrang - [lexical][lexical-playground] Chore: Refactor IME composition test infrastructure and add browser-level coverage ([#8793](https://github.com/facebook/lexical/pull/8793)) by @mayrang - [lexical-playground] Bug Fix: Use viewBox dimensions for unsized Excalidraw output ([#8798](https://github.com/facebook/lexical/pull/8798)) by @mayrang - [lexical-table] Bug Fix: Export $insertTableRowAtNode and $insertTableColumnAtNode ([#8791](https://github.com/facebook/lexical/pull/8791)) by @hamo-o - [lexical-playground][lexical-website] Feature: Add Vercel Analytics and Speed Insights ([#8796](https://github.com/facebook/lexical/pull/8796)) by @zurfyx - [lexical][lexical-eslint-plugin] Feature: Add $getDocument() API and Shadow DOM lint enforcement ([#8788](https://github.com/facebook/lexical/pull/8788)) by @mayrang - [scripts] Bug Fix: strip misplaced pure annotations from prod builds ([#8786](https://github.com/facebook/lexical/pull/8786)) by @etrepum - [lexical] Bug Fix: deleteCharacter overwrites X11 PRIMARY selection via Selection.modify ([#8774](https://github.com/facebook/lexical/pull/8774)) by @etrepum - [lexical-playground] Bug Fix: Support Unicode URLs in autolink matcher ([#8787](https://github.com/facebook/lexical/pull/8787)) by @mayrang - [lexical-table] Feature: Spread pasted TSV text across table cells ([#8780](https://github.com/facebook/lexical/pull/8780)) by @mayrang - [Breaking Change][lexical] Bug Fix: Preserve DOM element when composing on segmented TextNode middle ([#8784](https://github.com/facebook/lexical/pull/8784)) by @mayrang - [Breaking Change][lexical-react][lexical-devtools-core] Chore: Drop React 17 support, baseline is now React 18 ([#8782](https://github.com/facebook/lexical/pull/8782)) by @etrepum - [lexical-playground][lexical] Feature: Ruby annotation node with floating editor ([#8741](https://github.com/facebook/lexical/pull/8741)) by @mayrang - [lexical-playground] Feature: Find and Replace ([#8779](https://github.com/facebook/lexical/pull/8779)) by @mayrang - [lexical-playground] Bug Fix: restore RTL checkbox position in checklist ([#8783](https://github.com/facebook/lexical/pull/8783)) by @ryanda9910 - [lexical-rich-text] Bug Fix: Stop ArrowUp/Down from skipping block decorators ([#8775](https://github.com/facebook/lexical/pull/8775)) by @mayrang - [lexical-playground] Bug Fix: Convert remaining icon glyphs to mask-image for forced-colors support ([#8781](https://github.com/facebook/lexical/pull/8781)) by @mayrang - fix(lexical): use `extends` for type parameter bound in registerEventListeners flow type ([#8778](https://github.com/facebook/lexical/pull/8778)) by @potatowagon - [lexical] Bug Fix: Keep selection inside single-child inline elements ([#8772](https://github.com/facebook/lexical/pull/8772)) by @mayrang - [lexical][*] Feature: registerEventListener / registerEventListeners DOM helpers ([#8767](https://github.com/facebook/lexical/pull/8767)) by @etrepum - [lexical-playground] Bug Fix: Restore floating toolbar comment icon after mask-image conversion ([#8773](https://github.com/facebook/lexical/pull/8773)) by @mayrang - [lexical] Bug Fix: Skip ZWSP insertion for format mismatch on Android Chrome ([#8769](https://github.com/facebook/lexical/pull/8769)) by @mayrang - [lexical-a11y][lexical-react][lexical-playground][lexical-website] Feature: @lexical/a11y framework-agnostic accessibility helpers + WCAG AA reference adoption ([#8591](https://github.com/facebook/lexical/pull/8591)) by @mayrang - Add missing copyright headers to 4 source files ([#8768](https://github.com/facebook/lexical/pull/8768)) by @xiezhenjia-meta - [lexical-website] Bug Fix: Remove horizontal scroll on homepage hero ([#8760](https://github.com/facebook/lexical/pull/8760)) by @kainulla - [lexical-selection] Bug Fix: re-resolve detached firstBlock in insertNodes ([#8764](https://github.com/facebook/lexical/pull/8764)) by @ochevallier - [lexical] Modernize InlineFormattableNode Flow stub syntax rejected by fb-www flow strict ([#8763](https://github.com/facebook/lexical/pull/8763)) by @potatowagon - [lexical-utils] Bug Fix: positionNodeOnRange leaking orphan rect nodes when rects shrink ([#8762](https://github.com/facebook/lexical/pull/8762)) by @durvesh1992 - docs: fix duplicated words in comments and docs ([#8761](https://github.com/facebook/lexical/pull/8761)) by @durvesh1992 - [lexical-selection] Bug Fix: Properly handle block end focus in backward selections during $setBlocksType ([#8753](https://github.com/facebook/lexical/pull/8753)) by @ochevallier - [lexical][lexical-extension] Bug Fix: Align DecoratorTextNode format with TextNode in mixed selections ([#8737](https://github.com/facebook/lexical/pull/8737)) by @sahiee-dev - [lexical] Bug Fix: Clean up trailing shadow root after select-all delete ([#8751](https://github.com/facebook/lexical/pull/8751)) by @mayrang - [lexical][lexical-rich-text] Bug Fix: Place block cursor between decorators and shadow roots ([#8758](https://github.com/facebook/lexical/pull/8758)) by @mayrang - [lexical-playground] Bug Fix: Deduplicate speech-to-text insertion on Android Chrome ([#8759](https://github.com/facebook/lexical/pull/8759)) by @mayrang - [lexical] Bug Fix: Prevent deleteLine from removing adjacent block decorators ([#8744](https://github.com/facebook/lexical/pull/8744)) by @mayrang - build(deps): bump actions/checkout from 6 to 7 in the github-actions group ([#8757](https://github.com/facebook/lexical/pull/8757)) by @dependabot - [ci] Add internal-registry dependency availability check ([#8756](https://github.com/facebook/lexical/pull/8756)) by @zurfyx - [lexical] Bug Fix: Prevent text duplication on iOS Safari when formatting during composition ([#8755](https://github.com/facebook/lexical/pull/8755)) by @mayrang - [lexical-code][lexical-playground] Bug Fix: Prevent formatting on TabNode inside code blocks ([#8752](https://github.com/facebook/lexical/pull/8752)) by @mayrang - [lexical] Bug Fix: Defer onUpdate callbacks during nested commits ([#8672](https://github.com/facebook/lexical/pull/8672)) by @Rohithmatham12 - [lexical-extension][lexical-playground] Chore: Some cleanups ([#8732](https://github.com/facebook/lexical/pull/8732)) by @levensta - [lexical-markdown] Bug Fix: keep fence-like lines inside a code block as content ([#8734](https://github.com/facebook/lexical/pull/8734)) by @GermanJablo - v0.46.0 ([#8748](https://github.com/facebook/lexical/pull/8748)) by @etrepum ## New Contributors - @Rohithmatham12 made their first contribution in [#8672](https://github.com/facebook/lexical/pull/8672) - @kainulla made their first contribution in [#8760](https://github.com/facebook/lexical/pull/8760) - @durvesh1992 made their first contribution in [#8761](https://github.com/facebook/lexical/pull/8761) - @ochevallier made their first contribution in [#8753](https://github.com/facebook/lexical/pull/8753) - @ryanda9910 made their first contribution in [#8783](https://github.com/facebook/lexical/pull/8783) - @hamo-o made their first contribution in [#8791](https://github.com/facebook/lexical/pull/8791) - @vijayojha89 made their first contribution in [#8802](https://github.com/facebook/lexical/pull/8802) **Full Changelog**: https://lexical.dev is the project site; compare view: https://github.com/facebook/lexical/compare/v0.46.0...v0.47.0