v0.51.0
Graphify-Labs/graphifyv0.51.0Sep 17, 2026by etrepum
Upgrading?
AI Summary
v0.51.0 introduces declarative JSON serialization schemas via `$config` for nodes, enabling faster serialization and compact export options. It also deprecates `LexicalComposer` and migrates packages to ESM-only.
Key Highlights
- Declarative JSON serialization schemas using `$config`
- Compact JSON export option (omits default values)
- Generated serialization code via `@lexical/compiler`
- New `@lexical/fast-check` package for property-based testing
- Deprecation of `LexicalComposer` in favor of `LexicalExtensionComposer`
Breaking Changes
- npm packages are ESM only (no CommonJS `require` support)
- `exportJSON` may serialize instances as-is, leading to potential stale reference issues
- Deprecated Prism re-exports removed from `@lexical/code`
New Features
- Declarative serialization schemas (experimental)
- Compact JSON export
- Generated serialization code
- Subpath exports for `@lexical/extension`
- New `@lexical/fast-check` package
Full Release Notes
v0.51.0 is a monthly release with one large new feature: nodes can now declare their JSON serialization as a schema on `$config`. This declarative schema is faster, safer, and more flexible than the hand-written methods. The metadata it provides enables a compact export option with all default values elided, the code generator that provides faster import and export for every node that lexical ships, a new [`@lexical/fast-check`](https://lexical.dev/docs/api/modules/lexical_fast-check) package for property-based tests, and it provides a path to future features that rely on knowing the structure of the nodes (e.g. additional codecs and dev tools). This is a big step towards Lexical 1.0, the next few releases are expected to be focused on moving everything (including docs and examples) to the latest Extension and `$config` APIs and removing deprecated functionality. Two related changes in this release are that we are publishing ESM-only to npm now (cjs builds are still supported in the source tree), and `LexicalComposer` is deprecated for `LexicalExtensionComposer`. Expect anything `@deprecated` to be removed soon. ### Breaking Changes * **npm packages are ESM only.** Every package declares `"type": "module"` and its `exports` map offers `development` / `production` / `default` conditions with no `require` branch; the CommonJS build remains in-tree only for Meta's www. Bundlers are unaffected. CommonJS code can `require()` the packages on Node.js 20.19+ (the builds have no top-level `await`), and older Node.js must use `await import(...)` — but a dependency the app also loads through `require()` can then exist twice, which breaks handing its objects to Lexical (`yjs` docs to `@lexical/yjs`, `@preact/signals-core` signals from `@lexical/extension`), so load those as ESM too. Metro bundles both builds unless you add the condition for Lexical's packages; see the [module formats FAQ](https://lexical.dev/docs/faq) ([#9127](https://github.com/facebook/lexical/pull/9127)) * [`lexical`](https://lexical.dev/docs/api/modules/lexical) — **`exportJSON` may serialize the instance as-is.** A property declared with `withField` is read straight off the node instead of through its accessor, so `exportJSON` no longer resolves `getLatest()` for you and a stale reference can write stale values (and a property whose accessor a subclass overrode still resolves, so one object can mix the two). Nothing inside Lexical is affected — the walk, the clipboard selection export and `editorState.toJSON()` all start from the node map — but call `getLatest()` yourself on a reference you kept across a mutation ([#8602](https://github.com/facebook/lexical/pull/8602)) * [`@lexical/code`](https://lexical.dev/docs/api/modules/lexical_code) — the deprecated Prism re-exports are gone, along with the `@lexical/code-prism` dependency (so Prism no longer lands in a bundle that only imports `@lexical/code`). Import `CODE_LANGUAGE_FRIENDLY_NAME_MAP`, `CODE_LANGUAGE_MAP`, `getCodeLanguageOptions`, `getCodeLanguages`, `getCodeThemeOptions`, `getLanguageFriendlyName`, `normalizeCodeLanguage` (formerly also `normalizeCodeLang`), `PrismTokenizer` and `registerCodeHighlighting` from [`@lexical/code-prism`](https://lexical.dev/docs/api/modules/lexical_code_prism) ([#9141](https://github.com/facebook/lexical/pull/9141)) ### Deprecations * [`@lexical/react`](https://lexical.dev/docs/api/modules/lexical_react) — `LexicalComposer` is deprecated in favor of `LexicalExtensionComposer` and is expected to be removed in a future major. `LexicalComposer` cannot accept extensions, so any feature shipped as one is unreachable from an editor it builds; the migration is usually a two-line change ([#9168](https://github.com/facebook/lexical/pull/9168), [React extensions guide](https://lexical.dev/docs/extensions/react)) ### New APIs & Features * [`lexical`](https://lexical.dev/docs/api/modules/lexical) — **Declarative serialization schemas** (experimental). A node that uses `$config` declares its serialized properties once in the new `json` property, and that single declaration drives `importJSON`, `updateFromJSON` and `exportJSON`: `nodeSchema`, `withField` / `withAccessors`, and the value combinators (`stringValue`, `numberValue`, `booleanValue`, `enumValue`, `arrayValue`, `objectValue`, `unionValue`, `rawValue`, `transformValue`, `nullable`, `optional`, …). Every built-in node declares one, and most custom nodes now need no JSON serialization code at all. Output is unchanged by default ([#8602](https://github.com/facebook/lexical/pull/8602), [serialization docs](https://lexical.dev/docs/serialization/serialization)). * [`lexical`](https://lexical.dev/docs/api/modules/lexical) — **Compact JSON export**, opt-in via `editorState.toJSON(true)` or `$withCompactExport(true, cb)` (with `$isCompactExport()` for schema getters, plus `$exportNodeJSON` and the `CompactSerializedEditorState` / `ParsableSerializedEditorState` / `LexicalParseJSON` / `SerializedPartial` types). It omits properties equal to their schema default, properties the parser derives, and the deprecated `version`. The raw objects are well under half the legacy size — which matters for structured clones and worker messages — but after gzip the two are a wash. Both forms parse back to the same document; only a Lexical new enough to know the schemas can read the compact one, so keep writing the legacy form until every reader is upgraded ([#8602](https://github.com/facebook/lexical/pull/8602)) * [`@lexical/compiler`](https://lexical.dev/docs/api/modules/lexical_compiler) — **Generated serialization code.** Every built-in node class ships straight-line serialization generated from its own schema at build time, producing byte-identical JSON to the schema-driven path that continues to serve custom nodes ([#8602](https://github.com/facebook/lexical/pull/8602)) * [`@lexical/fast-check`](https://lexical.dev/docs/api/modules/lexical_fast-check) — New package deriving [fast-check](https://fast-check.dev) arbitraries from those schemas: `nodeArbitrary(NodeClass)` generates exactly the serialized JSON a node's parser accepts, each property independently present or absent. Useful for the bugs fixtures hide, such as a property `afterCloneFrom` forgot to copy. `fast-check` is a peer dependency; `getComposedSchemaFields` in core inspects a class's schema without generating anything ([#8602](https://github.com/facebook/lexical/pull/8602)) * [`@lexical/extension`](https://lexical.dev/docs/api/modules/lexical_extension) — Published as subpath exports, one entry per extension (`@lexical/extension/AutoFocusExtension`, …), with compiler and lint enforcement of the source import convention. The barrel import is unchanged, and shared modules such as signals keep a single instance ([#9161](https://github.com/facebook/lexical/pull/9161)). This is primarily only useful as a consumer if you are not using tree-shaking. ### Notable Fixes **Bundling, tree-shaking & types** * A production import of only `createCommand` no longer retains the editor ([#9121](https://github.com/facebook/lexical/pull/9121)), and the remaining module-scope side effects that defeated tree-shaking are gone, with a bare-import residue check now run over every entry ([#9124](https://github.com/facebook/lexical/pull/9124)); extension editors build under loose-mode transpilation ([#9134](https://github.com/facebook/lexical/pull/9134)) * Flow: `defineExtension` was uncallable, making the extension types unusable ([#9132](https://github.com/facebook/lexical/pull/9132)); declarations can now express an extension with dependencies ([#9176](https://github.com/facebook/lexical/pull/9176)); modern variance keywords survive into the www stubs ([#9154](https://github.com/facebook/lexical/pull/9154)) **Selection & editing** * No redundant selection-change command on Safari link selection ([#9163](https://github.com/facebook/lexical/pull/9163)); `TextNode.setMode`, `setTextContent` and `isSimpleText` read the latest state ([#9162](https://github.com/facebook/lexical/pull/9162)); `$removeTextFromCaretRange` no longer leaves a childless list or table as the root's only child ([#9116](https://github.com/facebook/lexical/pull/9116)); a text entity keeps the style and detail of the text it replaces ([#9130](https://github.com/facebook/lexical/pull/9130)); selection overlay listeners are notified when rectangles are removed ([#9117](https://github.com/facebook/lexical/pull/9117)) **Lists, tables & Markdown** * Indenting between two nested lists no longer converts the second list's type ([#9118](https://github.com/facebook/lexical/pull/9118)); `$mergeCells` no longer keeps the empty paragraph of the target cell ([#9122](https://github.com/facebook/lexical/pull/9122)); text left outside a Markdown link keeps its format ([#9131](https://github.com/facebook/lexical/pull/9131)) **Playground & docs** * Card/Review CSS placeholders are cleared reliably on paste in Safari ([#9129](https://github.com/facebook/lexical/pull/9129)) and releasing a CardNode drag no longer selects the node ([#9135](https://github.com/facebook/lexical/pull/9135)); new docs on Lexical being a singleton per app, and why a library must declare it as a peer dependency ([#9125](https://github.com/facebook/lexical/pull/9125)) Plus the usual dependency updates across the rollup, shikijs, vitest, docusaurus/typedoc and flow/hermes groups. ## What's Changed * v0.50.0 by @etrepum in https://github.com/facebook/lexical/pull/9110 * [lexical][lexical-compiler] Bug Fix: Let esbuild drop the editor from a createCommand-only production import by @zurfyx in https://github.com/facebook/lexical/pull/9121 * [*] Bug Fix: Remove the remaining module-scope side effects that defeat tree-shaking by @etrepum in https://github.com/facebook/lexical/pull/9124 * [lexical-playground] Bug Fix: clear Card/Review CSS placeholders reliably on paste in Safari by @sahiee-dev in https://github.com/facebook/lexical/pull/9129 * [lexical-website] Documentation Update: document that Lexical is a singleton per app and libraries must declare it as a peer dependency by @potatowagon in https://github.com/facebook/lexical/pull/9125 * [lexical-markdown] Bug Fix: text left outside a markdown link keeps its format by @Om-singhaI in https://github.com/facebook/lexical/pull/9131 * [lexical] Fix: make the extension Flow types usable (defineExtension was uncallable) by @potatowagon in https://github.com/facebook/lexical/pull/9132 * build(deps-dev): bump esbuild from 0.27.7 to 0.28.1 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9123 * [lexical-table] Bug Fix: $mergeCells no longer keeps the empty paragraph of the target cell by @Om-singhaI in https://github.com/facebook/lexical/pull/9122 * [lexical-utils] Bug Fix: notify when selection overlay rectangles are removed by @mehuljariwala in https://github.com/facebook/lexical/pull/9117 * [lexical] Bug Fix: $removeTextFromCaretRange no longer leaves a childless list or table as the root's only child by @Om-singhaI in https://github.com/facebook/lexical/pull/9116 * [lexical-playground] Bug Fix: avoid node selection on CardNode drag release by @kavyansh18 in https://github.com/facebook/lexical/pull/9135 * [lexical-extension] Fix: use Array.from over iterable spread so extension editors build under loose-mode transpilation by @potatowagon in https://github.com/facebook/lexical/pull/9134 * [lexical-text] Bug Fix: a text entity keeps the style and detail of the text it replaces by @Om-singhaI in https://github.com/facebook/lexical/pull/9130 * [*] Breaking change: Publish ESM only to npm and keep the CommonJS build for www by @etrepum in https://github.com/facebook/lexical/pull/9127 * [lexical-code] Breaking change: drop the deprecated prism re-exports and the @lexical/code-prism dependency by @etrepum in https://github.com/facebook/lexical/pull/9141 * build(deps-dev): bump vitest from 4.1.8 to 4.1.11 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9140 * build(deps): bump the docusaurus-and-typedoc group with 13 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9142 * build(deps-dev): bump the flow-and-hermes group with 4 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9143 * build(deps-dev): bump baseline-browser-mapping from 2.10.33 to 2.11.0 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9139 * build(deps): bump the shikijs group with 6 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9145 * build(deps): bump the rollup group across 1 directory with 5 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9144 * [lexical-list] Bug Fix: indenting between two nested lists no longer converts the second list's type by @Om-singhaI in https://github.com/facebook/lexical/pull/9118 * [*] Bug Fix: Keep modern Flow variance keywords in the www Flow stubs by @potatowagon in https://github.com/facebook/lexical/pull/9154 * build(deps-dev): bump the dev-dependencies group across 1 directory with 26 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9150 * build(deps-dev): bump flow-bin from 0.330.0 to 0.331.0 in the flow-and-hermes group by @dependabot[bot] in https://github.com/facebook/lexical/pull/9156 * [lexical-extension][*] Refactor: publish @lexical/extension as subpath exports with compiler+lint enforcement by @etrepum in https://github.com/facebook/lexical/pull/9161 * [lexical] Bug Fix: Avoid redundant selection change command by @levensta in https://github.com/facebook/lexical/pull/9163 * [lexical] Bug Fix: TextNode setMode, setTextContent and isSimpleText read the latest state by @Dev-next-gen in https://github.com/facebook/lexical/pull/9162 * [lexical-react] Chore: Deprecate LexicalComposer in favor of LexicalExtensionComposer by @potatowagon in https://github.com/facebook/lexical/pull/9168 * build(deps-dev): bump eslint from 10.9.1 to 10.10.0 in the dev-dependencies group across 1 directory by @dependabot[bot] in https://github.com/facebook/lexical/pull/9158 * build(deps): bump date-fns from 4.1.0 to 4.4.0 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9159 * [lexical][*] Feature: node JSON serialization schemas, with compact export by @etrepum in https://github.com/facebook/lexical/pull/8602 * build(deps): bump @babel/parser from 8.0.0 to 8.0.4 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9160 * build(deps): bump immutable from 4.3.8 to 4.3.9 by @dependabot[bot] in https://github.com/facebook/lexical/pull/9175 * build(deps-dev): bump the vitest group across 1 directory with 2 updates by @dependabot[bot] in https://github.com/facebook/lexical/pull/9157 * [lexical] Fix: Flow declarations cannot express an extension with dependencies by @potatowagon in https://github.com/facebook/lexical/pull/9176 ## New Contributors * @mehuljariwala made their first contribution in https://github.com/facebook/lexical/pull/9117 * @kavyansh18 made their first contribution in https://github.com/facebook/lexical/pull/9135 * @Dev-next-gen made their first contribution in https://github.com/facebook/lexical/pull/9162 **Full Changelog**: https://github.com/facebook/lexical/compare/v0.50.0...v0.51.0
Related Repositories
public-apis/public-apis★ 491,126
A collective list of free APIs
NousResearch/hermes-agent★ 255,898
The agent that grows with you
yt-dlp/yt-dlp★ 199,995
A feature-rich command-line audio/video downloader
microsoft/markitdown★ 191,479
Python tool for converting files and office documents to Markdown.
Significant-Gravitas/AutoGPT★ 187,699
AutoGPT is the vision of accessible AI for everyone, to use and to build on. Our mission is to provide the tools, so that you can focus on what matters.