Skip to main content
Nodes are the building blocks of content in Lexical. Every piece of content is represented by a node in the editor state tree.

Node Hierarchy

Lexical provides several base node classes:
  • LexicalNode - Abstract base class for all nodes
  • TextNode - Represents text content
  • ElementNode - Container for child nodes
  • DecoratorNode - Renders custom content

LexicalNode

The base class for all nodes. Cannot be instantiated directly.

Static Methods

getType

static getType(): string
Returns the unique string type identifier for this node class.
type
string
The node type identifier

clone

static clone(node: LexicalNode): LexicalNode
Creates a new node instance by cloning the provided node.
node
LexicalNode
required
The node to clone
clone
LexicalNode
A new node instance with the same properties

importJSON

static importJSON(serializedNode: SerializedLexicalNode): LexicalNode
Deserializes a node from JSON.
serializedNode
SerializedLexicalNode
required
The serialized node data
node
LexicalNode
The deserialized node

Instance Methods

getType

getType(): string
Returns the type string for this node instance.

getKey

getKey(): NodeKey
Returns this node’s unique key.
key
NodeKey
The node’s key (string)

getLatest

getLatest(): this
Returns the latest version of this node from the active EditorState.
node
this
The latest version of this node

getWritable

getWritable(): this
Returns a mutable version of this node. Must be called inside editor.update().
node
this
A writable clone of this node
editor.update(() => {
  const node = $getNodeByKey('some-key');
  const writable = node.getWritable();
  // Now you can mutate writable
});

getParent

getParent<T extends ElementNode>(): T | null
Returns this node’s parent node.
parent
ElementNode | null
The parent node or null

getParentOrThrow

getParentOrThrow<T extends ElementNode>(): T
Returns this node’s parent node or throws if none exists.

getTopLevelElement

getTopLevelElement(): ElementNode | DecoratorNode | null
Returns the highest ancestor that is not a root node.

getParents

getParents(): Array<ElementNode>
Returns all ancestor nodes up to the root.

getPreviousSibling

getPreviousSibling<T extends LexicalNode>(): T | null
Returns the previous sibling node.

getNextSibling

getNextSibling<T extends LexicalNode>(): T | null
Returns the next sibling node.

isAttached

isAttached(): boolean
Returns true if there is a path from this node to the root.
attached
boolean
True if the node is attached to the editor state

isSelected

isSelected(selection?: BaseSelection): boolean
Returns true if this node is in the provided selection (or current selection).
selection
BaseSelection
The selection to check against (defaults to current selection)
selected
boolean
True if the node is selected

remove

remove(preserveEmptyParent?: boolean): void
Removes this node from the editor state.
preserveEmptyParent
boolean
If false (default), removes parent if it becomes empty

replace

replace<N extends LexicalNode>(replaceWith: N, includeChildren?: boolean): N
Replaces this node with another node.
replaceWith
LexicalNode
required
The node to replace this one with
includeChildren
boolean
Whether to transfer children to the new node
node
N
The replacement node

insertBefore

insertBefore(nodeToInsert: LexicalNode, restoreSelection?: boolean): LexicalNode
Inserts a node before this one as a sibling.

insertAfter

insertAfter(nodeToInsert: LexicalNode, restoreSelection?: boolean): LexicalNode
Inserts a node after this one as a sibling.

isBefore

isBefore(targetNode: LexicalNode): boolean
Returns true if this node comes before the target in the tree.

isParentOf

isParentOf(targetNode: LexicalNode): boolean
Returns true if this node is an ancestor of the target.

getTextContent

getTextContent(): string
Returns the text content of this node.

getTextContentSize

getTextContentSize(): number
Returns the length of the text content.

createDOM

createDOMConfig: EditorConfig, editor: LexicalEditor): HTMLElement
Creates the DOM element for this node during reconciliation.

updateDOM

updateDOM(prevNode: this, dom: HTMLElement, config: EditorConfig): boolean
Updates the DOM element. Return true to recreate the DOM.

exportJSON

exportJSON(): SerializedLexicalNode
Serializes this node to JSON.

exportDOM

exportDOM(editor: LexicalEditor): DOMExportOutput
Exports this node as HTML.

TextNode

Represents text content with formatting.

Creating Text Nodes

import { $createTextNode } from 'lexical';

const textNode = $createTextNode('Hello world');

$createTextNode

function $createTextNode(text?: string): TextNode
text
string
default:"''"
The text content
node
TextNode
A new TextNode instance

$isTextNode

function $isTextNode(node: LexicalNode | null | undefined): node is TextNode
Type guard for TextNode.

TextNode Methods

getTextContent

getTextContent(): string
Returns the text content.

setTextContent

setTextContent(text: string): this
Sets the text content.
text
string
required
The new text content

getFormat

getFormat(): number
Returns the format flags as a 32-bit integer.

hasFormat

hasFormat(type: TextFormatType): boolean
Returns true if the format type is applied.
type
TextFormatType
required
Format type: ‘bold’, ‘italic’, ‘underline’, ‘strikethrough’, ‘code’, ‘subscript’, ‘superscript’, ‘highlight’, ‘lowercase’, ‘uppercase’, ‘capitalize’

setFormat

setFormat(format: TextFormatType | number): this
Sets the text format.

toggleFormat

toggleFormat(type: TextFormatType): this
Toggles a specific format on or off.
editor.update(() => {
  const textNode = $createTextNode('Bold text');
  textNode.toggleFormat('bold');
});

getStyle

getStyle(): string
Returns the inline CSS styles as a string.

setStyle

setStyle(style: string): this
Sets inline CSS styles.
style
string
required
CSS text (e.g., ‘color: red; font-size: 16px’)

getMode

getMode(): TextModeType
Returns the text mode: ‘normal’, ‘token’, or ‘segmented’.

setMode

setMode(type: TextModeType): this
Sets the text mode.

isSimpleText

isSimpleText(): boolean
Returns true if this is a simple text node (type ‘text’, normal mode).

isToken

isToken(): boolean
Returns true if in token mode (deleted as a unit).

isSegmented

isSegmented(): boolean
Returns true if in segmented mode.

splitText

splitText(...splitOffsets: Array<number>): Array<TextNode>
Splits this text node at the specified offsets.
splitOffsets
number[]
required
Character offsets to split at
nodes
TextNode[]
The resulting text nodes
editor.update(() => {
  const textNode = $createTextNode('Hello World');
  const [hello, world] = textNode.splitText(5); // Split at space
});

select

select(anchorOffset?: number, focusOffset?: number): RangeSelection
Creates a selection on this text node.
anchorOffset
number
Anchor position (defaults to end)
focusOffset
number
Focus position (defaults to end)

ElementNode

A container node that can have children.

$isElementNode

function $isElementNode(node: LexicalNode | null | undefined): node is ElementNode
Type guard for ElementNode.

ElementNode Methods

getChildren

getChildren<T extends LexicalNode>(): Array<T>
Returns all child nodes.

getChildrenSize

getChildrenSize(): number
Returns the number of children.

isEmpty

isEmpty(): boolean
Returns true if there are no children.

getFirstChild

getFirstChild<T extends LexicalNode>(): T | null
Returns the first child node.

getLastChild

getLastChild<T extends LexicalNode>(): T | null
Returns the last child node.

getChildAtIndex

getChildAtIndex<T extends LexicalNode>(index: number): T | null
Returns the child at the specified index.

append

append(...nodesToAppend: Array<LexicalNode>): this
Appends nodes as children.
editor.update(() => {
  const paragraph = $createParagraphNode();
  const text = $createTextNode('Hello');
  paragraph.append(text);
});

clear

clear(): this
Removes all children.

splice

splice(
  start: number,
  deleteCount: number,
  nodesToInsert: Array<LexicalNode>
): this
Inserts/removes children at an index.

getFormat

getFormat(): number
Returns the element format flags.

getFormatType

getFormatType(): ElementFormatType
Returns the format type: ‘left’, ‘center’, ‘right’, ‘justify’, ‘start’, ‘end’, or ”.

setFormat

setFormat(type: ElementFormatType): this
Sets the element alignment/format.

getIndent

getIndent(): number
Returns the indentation level.

setIndent

setIndent(indent: number): this
Sets the indentation level.

DecoratorNode

A node that renders custom content via a decorator.

$isDecoratorNode

function $isDecoratorNode<T>(node: LexicalNode | null | undefined): node is DecoratorNode<T>
Type guard for DecoratorNode.

DecoratorNode Methods

decorate

decorate(editor: LexicalEditor, config: EditorConfig): T
Returns the decorator value (e.g., a React component).

isInline

isInline(): boolean
Returns true if the decorator is inline.

isIsolated

isIsolated(): boolean
Returns true if the decorator is isolated from surrounding content.

isKeyboardSelectable

isKeyboardSelectable(): boolean
Returns true if the decorator can be selected via keyboard.

Built-in Node Types

ParagraphNode

import { $createParagraphNode, $isParagraphNode } from 'lexical';

const paragraph = $createParagraphNode();

LineBreakNode

import { $createLineBreakNode, $isLineBreakNode } from 'lexical';

const lineBreak = $createLineBreakNode();

TabNode

import { $createTabNode, $isTabNode } from 'lexical';

const tab = $createTabNode();

RootNode

import { $getRoot, $isRootNode } from 'lexical';

const root = $getRoot();

Creating Custom Nodes

Extend a base node class:
import { ElementNode } from 'lexical';

export class CustomNode extends ElementNode {
  static getType(): string {
    return 'custom';
  }
  
  static clone(node: CustomNode): CustomNode {
    return new CustomNode(node.__key);
  }
  
  createDOM(config: EditorConfig): HTMLElement {
    const element = document.createElement('div');
    element.className = 'custom-node';
    return element;
  }
  
  updateDOM(): boolean {
    return false;
  }
  
  static importJSON(serializedNode: SerializedCustomNode): CustomNode {
    return $createCustomNode();
  }
  
  exportJSON(): SerializedCustomNode {
    return {
      ...super.exportJSON(),
      type: 'custom',
      version: 1,
    };
  }
}

export function $createCustomNode(): CustomNode {
  return new CustomNode();
}

export function $isCustomNode(node: LexicalNode | null | undefined): node is CustomNode {
  return node instanceof CustomNode;
}
Register with the editor:
const editor = createEditor({
  nodes: [CustomNode]
});