Skip to main content

📝 Lexical Builder 🛠️

A Unified Model for Extending Lexical

Solved Problems

Modularized editor configuration
Each Plan can specify partial editor configuration (nodes, theme, DOM import/export, etc.) that are all merged to build the editor
Combined config + registration
Generally there are interdependencies between configuration and behavior, e.g. the ListPlugin requires ListNode and ListItemNode and vice versa.
Hassle-free dependencies
A Plan is completely self-contained, and specifies all dependencies to make it work. If you want checklists, add CheckListPlan as a dependency to your editor's plan. No more missing Node errors or silently absent behavior.
Optional peer dependencies
Have an optional dependency? No problem. You can even specify config overrides if peer dependencies are present! This is used internally so Plans can provide an error if a suitable framework host is not available (e.g. ReactPlan is used, but there's no LexicalPlanComposer or ReactPluginHostPlan)
Framework independent
Many Plugins don't really need React, but the only legacy convention is to expose as much behavior as possible in a React component even if it just calls some register functions and returns null.
React anywhere
Non-React users can use the ReactPluginHostPlan to use React Plans or legacy Plugins! This of course still uses React at runtime, but does not force the user to learn React, use JSX syntax, or have any direct React dependency in their project.
Extensible config
Each Plan can specify its own optional typed configuration of any kind, that can be specified by any other plan, and is accessible at runtime anywhere you can get an editor reference (even in a Node!). No need to shoehorn properties into the editor-global EditorTheme { [key: string]: any } or set up a module-global WeakMap<Editor, Config> workaround.
Outputs
A Plan can specify type-safe outputs, which are computed when the plan is registered to the editor (so can take configuration, the editor, and dependencies into account). These can be used by dependencies, or anywhere you have an editor reference. Think of it like having a sort of React style context for each Plan in your editor!

Adding a Plugin

🧩 Using Legacy (React) Plugins

🗂️ Using Lexical Builder Plans