Node Base Classes
Lexical provides three base classes you can extend:- TextNode - For inline text content with formatting
- ElementNode - For block-level or container elements
- DecoratorNode - For React components or custom DOM rendering
Creating a Custom TextNode
ExtendTextNode when you need custom inline text with additional properties:
packages/lexical-playground/src/nodes/EmojiNode.tsx for the complete implementation.
Creating a Custom ElementNode
ExtendElementNode for block-level or container elements:
packages/lexical-rich-text/src/index.ts for the complete QuoteNode implementation.
Creating a Custom DecoratorNode
ExtendDecoratorNode when you need to render a React component:
Required Methods
All custom nodes must implement:getType() - Returns a unique string identifierclone() - Creates a copy of the nodeimportJSON() - Deserializes from JSONRegistering Custom Nodes
Register your custom nodes in the editor configuration:Best Practices
- Immutability: Always use
getWritable()before modifying node properties - Factory Functions: Export a
$createYourNode()function (follows$convention) - Type Guards: Export a
$isYourNode()type guard function - Serialization: Ensure all custom properties are serialized in
exportJSON() - DOM Conversion: Implement
importDOM()for paste/HTML support - Property Access: Use
getLatest()when reading properties to get the current version
Node Lifecycle
- Construction: Node is created with
new YourNode()or factory function - Registration: Node class is registered in editor config
- Reconciliation:
createDOM()is called during first render - Updates:
updateDOM()is called when node changes - Cloning:
clone()is called when node is copied or made writable - Serialization:
exportJSON()is called for persistence - Deserialization:
importJSON()is called when loading saved content
See Also
- API Reference: LexicalNode
- API Reference: TextNode
- API Reference: ElementNode
- API Reference: DecoratorNode
- Source:
packages/lexical/src/LexicalNode.ts - Examples:
packages/lexical-playground/src/nodes/