General Questions
What is Lexical?
What is Lexical?
- Framework-agnostic core with React bindings
- Immutable state model with time-travel capabilities
- Built-in accessibility and WCAG compliance
- Plugin-based architecture
- Collaborative editing via Yjs
- Rich content support (tables, lists, code, images)
- TypeScript and Flow type definitions
How is Lexical different from other editors?
How is Lexical different from other editors?
Can I use Lexical without React?
Can I use Lexical without React?
What browsers does Lexical support?
What browsers does Lexical support?
- Chrome 86+
- Firefox 115+
- Safari 15+
- Edge 86+
Architecture & Concepts
What is the $ function convention?
What is the $ function convention?
$ (e.g., $getRoot(), $getSelection()) can only be called within:editor.update(() => {...})- for mutationseditor.read(() => {...})- for read-only access- Node transforms and command handlers (which have implicit update context)
What is EditorState and why is it immutable?
What is EditorState and why is it immutable?
- A node tree (hierarchical structure)
- Selection object (cursor/selection state)
- Everything needed to reconstruct the editor
- Enables reliable undo/redo
- Time-travel debugging
- Predictable updates
- Easy serialization to JSON
- Safe concurrent reads
- Current state is cloned as work-in-progress
- Your mutations modify the WIP state
- DOM reconciler diffs and applies changes
- New immutable state becomes current
How does the update/read cycle work?
How does the update/read cycle work?
- Clones current EditorState
- Applies your mutations to work-in-progress
- Batches multiple synchronous updates
- Runs transforms
- Reconciles DOM
- Fires listeners
- Flushes any pending updates first
- Provides read-only access to reconciled state
- Cannot make mutations
- Inside
update()you see pending state (pre-transform) editor.getEditorState().read()always uses latest reconciled state- Don’t nest reads in updates or vice versa (except read at end of update)
What are Node Transforms?
What are Node Transforms?
- Text replacements (markdown shortcuts, emoji)
- Validation and normalization
- Automatic formatting
- Custom node behaviors
How do Commands work?
How do Commands work?
Working with Nodes
How do I create a custom node?
How do I create a custom node?
When should I use TextNode vs ElementNode vs DecoratorNode?
When should I use TextNode vs ElementNode vs DecoratorNode?
- Inline text content
- Supports formatting (bold, italic, etc.)
- Examples: regular text, links, mentions
- Block or container elements
- Can have children (other nodes)
- Examples: paragraphs, headings, lists, divs
- Custom React/DOM components
- Non-text content
- Examples: images, videos, embeds, widgets
Why can't I modify a node directly?
Why can't I modify a node directly?
getWritable():How do Node Keys work?
How do Node Keys work?
- Keys are runtime-only, not serialized
- Use keys to identify nodes within an update
- Node methods automatically resolve to latest version via key
- Don’t store node references across update boundaries
Common Patterns
How do I listen to editor changes?
How do I listen to editor changes?
registerUpdateListener:register* methods return cleanup functions:useEffect:How do I implement markdown shortcuts?
How do I implement markdown shortcuts?
@lexical/markdown:How do I handle copy/paste?
How do I handle copy/paste?
How do I implement undo/redo?
How do I implement undo/redo?
Performance & Best Practices
How do I optimize performance with large documents?
How do I optimize performance with large documents?
- Batch updates: Multiple synchronous
editor.update()calls are automatically batched - Avoid unnecessary reads:
editor.read()flushes pending updates - Use transforms wisely: They run on every relevant node change
- Debounce listeners: Don’t do heavy work in every update listener
- Lazy load plugins: Only register plugins you need
Should I use plugins or transforms?
Should I use plugins or transforms?
- UI components
- Event handlers
- Command handlers
- Lifecycle management
- Automatic node mutations
- Text replacements
- Validation
- Format normalization
How do I debug Lexical editors?
How do I debug Lexical editors?
-
Tree View Plugin: Visualize node structure
- DevTools: Browser extension for inspecting EditorState
-
State Inspection:
-
Update Tags: Track update sources