Skip to main content
The LexicalEditor is the core controller for a Lexical editor instance. It manages the editor state, listeners, commands, and reconciliation.

Creating an Editor

createEditor

function createEditor(config?: CreateEditorArgs): LexicalEditor
Creates a new LexicalEditor instance. This is the lowest-level initialization API.
config
CreateEditorArgs
Configuration options for the editor
editor
LexicalEditor
A new LexicalEditor instance
import { createEditor } from 'lexical';

const editor = createEditor({
  namespace: 'MyEditor',
  theme: {
    paragraph: 'editor-paragraph',
    text: {
      bold: 'editor-text-bold',
      italic: 'editor-text-italic'
    }
  },
  onError: (error) => console.error(error)
});

State Management

getEditorState

getEditorState(): EditorState
Returns the current active EditorState.
state
EditorState
The current editor state

setEditorState

setEditorState(editorState: EditorState, options?: EditorSetOptions): void
Imperatively sets the EditorState, triggering reconciliation.
editorState
EditorState
required
The new editor state to set
options
EditorSetOptions

parseEditorState

parseEditorState(
  maybeStringifiedEditorState: string | SerializedEditorState,
  updateFn?: () => void
): EditorState
Parses a serialized EditorState from JSON.
maybeStringifiedEditorState
string | SerializedEditorState
required
JSON string or object to parse
updateFn
() => void
Optional update function to run during parsing
state
EditorState
The parsed editor state

Updates and Reads

update

update(updateFn: () => void, options?: EditorUpdateOptions): void
Executes an update to the editor state. This is the ONLY place where Lexical editor state can be safely mutated.
updateFn
() => void
required
Function with access to writable editor state. Can call $ functions.
options
EditorUpdateOptions
editor.update(() => {
  const root = $getRoot();
  const paragraph = $createParagraphNode();
  root.append(paragraph);
});

read

read<T>(callbackFn: () => T): T
Executes a read-only operation on the editor state. Any pending updates are flushed before the read.
callbackFn
() => T
required
Function with read-only access to editor state. Can call $ functions.
result
T
The return value from callbackFn
const textContent = editor.read(() => {
  return $getRoot().getTextContent();
});

Listeners

registerUpdateListener

registerUpdateListener(listener: UpdateListener): () => void
Registers a listener that triggers after each editor update.
listener
UpdateListener
required
Callback receiving UpdateListenerPayload
unregister
() => void
Function to remove the listener
const removeListener = editor.registerUpdateListener(({ editorState }) => {
  editorState.read(() => {
    const root = $getRoot();
    console.log('Content updated:', root.getTextContent());
  });
});

registerCommand

registerCommand<P>(
  command: LexicalCommand<P>,
  listener: CommandListener<P>,
  priority: CommandListenerPriority
): () => void
Registers a command listener. Commands are dispatched with dispatchCommand.
command
LexicalCommand<P>
required
The command to listen for
listener
CommandListener<P>
required
Handler function. Return true to stop propagation.
priority
CommandListenerPriority
required
Priority level (0-4). Higher priority runs first.
unregister
() => void
Function to remove the listener
import { FORMAT_TEXT_COMMAND, COMMAND_PRIORITY_NORMAL } from 'lexical';

const unregister = editor.registerCommand(
  FORMAT_TEXT_COMMAND,
  (formatType) => {
    // Handle format command
    return false; // Allow other handlers to run
  },
  COMMAND_PRIORITY_NORMAL
);

registerNodeTransform

registerNodeTransform<T extends LexicalNode>(
  klass: Klass<T>,
  listener: Transform<T>
): () => void
Registers a transform that runs when nodes of the specified type are marked dirty.
klass
Klass<T>
required
The node class to transform
listener
Transform<T>
required
Transform function receiving the dirty node
unregister
() => void
Function to remove the transform
import { TextNode } from 'lexical';

editor.registerNodeTransform(TextNode, (node) => {
  // Transform text nodes as they change
  const text = node.getTextContent();
  if (text.includes('@')) {
    // Handle mentions
  }
});

registerMutationListener

registerMutationListener(
  klass: Klass<LexicalNode>,
  listener: MutationListener,
  options?: MutationListenerOptions
): () => void
Registers a listener for when nodes of a specific type are created, updated, or destroyed.
klass
Klass<LexicalNode>
required
The node class to observe
listener
MutationListener
required
Callback receiving mutations
options
MutationListenerOptions
unregister
() => void
Function to remove the listener

registerTextContentListener

registerTextContentListener(listener: TextContentListener): () => void
Registers a listener for when the editor’s text content changes.
listener
(text: string) => void
required
Callback receiving the new text content
unregister
() => void
Function to remove the listener

registerRootListener

registerRootListener(listener: RootListener): () => void
Registers a listener for when the root DOM element changes.
listener
RootListener
required
Callback receiving new and previous root elements
unregister
() => void
Function to remove the listener

registerEditableListener

registerEditableListener(listener: EditableListener): () => void
Registers a listener for when the editor’s editable state changes.
listener
(editable: boolean) => void
required
Callback receiving the new editable state
unregister
() => void
Function to remove the listener

registerDecoratorListener

registerDecoratorListener<T>(listener: DecoratorListener<T>): () => void
Registers a listener for when the editor’s decorator object changes.
listener
DecoratorListener<T>
required
Callback receiving the decorators map
unregister
() => void
Function to remove the listener

Commands

dispatchCommand

dispatchCommand<TCommand extends LexicalCommand<unknown>>(
  type: TCommand,
  payload: CommandPayloadType<TCommand>
): boolean
Dispatches a command to all registered listeners.
type
LexicalCommand
required
The command to dispatch
payload
any
required
The command payload
handled
boolean
True if a listener stopped propagation
import { FORMAT_TEXT_COMMAND } from 'lexical';

editor.dispatchCommand(FORMAT_TEXT_COMMAND, 'bold');

Focus and Selection

focus

focus(callbackFn?: () => void, options?: EditorFocusOptions): void
Focuses the editor.
callbackFn
() => void
Callback to run after focus
options
EditorFocusOptions

blur

blur(): void
Removes focus from the editor.

Root Element

getRootElement

getRootElement(): null | HTMLElement
Returns the current root contenteditable element.
element
HTMLElement | null
The root element or null

setRootElement

setRootElement(nextRootElement: null | HTMLElement): void
Sets the root contenteditable element.
nextRootElement
HTMLElement | null
required
The new root element

getElementByKey

getElementByKey(key: NodeKey): HTMLElement | null
Returns the DOM element associated with a node key.
key
NodeKey
required
The node key
element
HTMLElement | null
The DOM element or null

Other Methods

isEditable

isEditable(): boolean
Returns whether the editor is currently editable.
editable
boolean
True if editable

setEditable

setEditable(editable: boolean): void
Sets the editor’s editable state.
editable
boolean
required
Whether the editor should be editable

isComposing

isComposing(): boolean
Returns whether the editor is currently in composition mode (IME input).
composing
boolean
True if composing

getKey

getKey(): string
Returns the editor’s unique key.
key
string
The editor key

getDecorators

getDecorators<T>(): Record<NodeKey, T>
Returns a map of all decorators in the editor.
decorators
Record<NodeKey, T>
Map of node keys to decorator values

hasNode

hasNode<T extends Klass<LexicalNode>>(node: T): boolean
Returns whether a node type is registered.
node
Klass<LexicalNode>
required
The node class to check
hasNode
boolean
True if the node type is registered

hasNodes

hasNodes<T extends Klass<LexicalNode>>(nodes: Array<T>): boolean
Returns whether all provided node types are registered.
nodes
Array<Klass<LexicalNode>>
required
The node classes to check
hasNodes
boolean
True if all node types are registered

toJSON

toJSON(): SerializedEditor
Serializes the editor to JSON.
json
SerializedEditor
The serialized editor state

Constants

Command Priorities

COMMAND_PRIORITY_EDITOR = 0
COMMAND_PRIORITY_LOW = 1
COMMAND_PRIORITY_NORMAL = 2
COMMAND_PRIORITY_HIGH = 3
COMMAND_PRIORITY_CRITICAL = 4
Priority levels for command listeners. Higher priority listeners execute first.

Build docs developers (and LLMs) love