Plate
PlateEditorsTemplates
GitHub16kGitHub
DiscordDiscord
  • Plate
  • Editor API
  • Editor Transforms
  • Node
  • Element
  • Text
  • Path
  • Point
  • Range
  • Location
  • Anchor
  • Selection
  • Document Change
  • DOM API
  • React Hooks
  • Plate Core
    • Plate Components
    • Plate Editor
    • Plate Plugin
    • Editor Context
    • Plate Controller
  • Plate Utils
  • Resizable

Plate Editor

PreviousNext

API reference for the Plate editor runtime.

Editor is the editor type returned by createEditor and useCreateEditor. The selected import path decides whether the instance is headless or React-enabled. Both forms expose typed plugin portals, api, editor.update() transactions, and editor-local plugin stores.

Ownership

ImportConstructorNotes
platejscreateEditor(options)Headless Plate editor for server and non-React code.
Plate ComponentsPlate Plugin

On This Page

OwnershipEditor shapeRuntime statePlugin accessDynamic descriptorsInitializationCore APIsCore transactionsPlugin pipeline effectsType helpersRelated APIs
Build your editor
Production-ready AI template and reusable components.
Get all-access
platejs/reactcreateEditor(options) or useCreateEditor(options)React-enabled editor with components, stores, DOM integration, and hooks.

Import the matching Editor type from the same entrypoint as the constructor.

Editor shape

The editor owns document reads, transactions, typed plugin access, DOM services, and lifecycle state.

Attributes

    Unique editor instance id. createEditor uses the provided id or creates one with nanoid().

    Read current document children with editor.read.children(), selection with editor.read.selection(), and the latest published commit with editor.read.lastCommit().

    Core Plate APIs, explicit editor-wide APIs, and installed plugin APIs inferred under their plugin names.

    Transaction entrypoint for document, selection, history, and plugin commands.

    Return the descriptor-scoped portal for a plugin's API, update commands, schema identity, and store. The descriptor supplies the inferred type.

    Public Plate runtime-instance and lifecycle state. Compiled plugin registries stay private to Plate.

Runtime state

React and DOM runtime state is read through Plate runtime APIs. Plate exposes only editor identity and lifecycle fields on editor.runtime; compiled plugin registries are private implementation data.

StateRead pathSet by
compositioneditor.api.react.isComposing()Plate React composition runtime.
focuseditor.api.react.isFocused()Plate React focus runtime.
read-onlyeditor.read.view.isReadOnly() or editor.api.react.isReadOnly()createEditor, <EditorRoot>, and <EditorContent>.
FieldTypeNotes
userIdstring | null | undefinedCollaborative identity passed through editor options.
isNormalizingboolean | undefinedtrue while Plate applies initial-value normalization.

Plugin access

Pass the installed descriptor to editor.plugin(Plugin). TypeScript infers that plugin's API, reads, update commands, schema identity, and editor-local state. Keep the descriptor's inferred type at call sites.

Plugin API and state
import { createEditor, definePlugin } from 'platejs';
 
const PanelPlugin = definePlugin('panel', {
  initialState: { open: false },
  api: ({ store }) => ({
    isOpen: () => store.get('open'),
  }),
});
 
const editor = createEditor({ plugins: [PanelPlugin] });
const panel = editor.plugin(PanelPlugin);
 
const open = panel.store.get('open');
const sameApi = editor.api.panel === panel.api;
Plugin API and state
import { createEditor, definePlugin } from 'platejs';
 
const PanelPlugin = definePlugin('panel', {
  initialState: { open: false },
  api: ({ store }) => ({
    isOpen: () => store.get('open'),
  }),
});
 
const editor = createEditor({ plugins: [PanelPlugin] });
const panel = editor.plugin(PanelPlugin);
 
const open = panel.store.get('open');
const sameApi = editor.api.panel === panel.api;

editor.api.panel and panel.api reference the same immutable API object. Use editor.read.<name> for plugin reads on a concrete editor, or editor.plugin(Plugin).read when the descriptor supplies the exact contract.

AccessUse it for
editor.plugin(Plugin).installedCheck installation before reading another field when the plugin is optional.
editor.plugin(Plugin).apiCall plugin services inferred from the descriptor.
editor.plugin(Plugin).readRun plugin-owned reads against current editor state.
editor.plugin(Plugin).updateRun a plugin-owned transaction command.
editor.plugin(Plugin).store.get(key, ...args)Read a state field or named selector result.
editor.plugin(Plugin).store.get()Read the complete current plugin state.
editor.plugin(Plugin).schema.typeRead an element descriptor's installed node type.
editor.plugin(Plugin).schema.keyRead a primary-mark descriptor's installed property key.

Behavior-only descriptors do not expose a consumer schema. A descriptor lookup checks the descriptor family as well as the name.

In React, use useEditor().plugin(Plugin) for the inferred portal. usePluginStore(Plugin, key) or usePluginStore(Plugin, selector) subscribes the component to plugin state.

Dynamic descriptors

editor.plugin requires a descriptor. When application data selects a capability at runtime, resolve that value through an application-owned map of allowed descriptors, then pass the selected descriptor to editor.plugin.

Check .installed first when absence is valid. Read .schema.type only when the caller expects an element plugin, or .schema.key when it expects a primary mark. A mismatched schema kind throws. A name does not prove a descriptor family or provide its typed API, update, and store contract.

Initialization

useCreateEditor memoizes the React createEditor constructor. The React entrypoint creates each plugin's editor-local store from initialState and installs React core plugins before user plugins.

Create a typed editor
import { useCreateEditor } from "platejs/react";
import { BoldPlugin } from "platejs/react";
 
export function useBasicEditor() {
  return useCreateEditor({
    plugins: [BoldPlugin],
    initialValue: [
      {
        type: "paragraph",
        children: [{ text: "Bold text is ready." }],
      },
    ],
  });
}
Create a typed editor
import { useCreateEditor } from "platejs/react";
import { BoldPlugin } from "platejs/react";
 
export function useBasicEditor() {
  return useCreateEditor({
    plugins: [BoldPlugin],
    initialValue: [
      {
        type: "paragraph",
        children: [{ text: "Bold text is ready." }],
      },
    ],
  });
}

The headless createEditor performs the shared setup:

StepBehavior
Runtime statePreserves Plate editor.id and initializes runtime.userId.
Plugin accessPublishes installed APIs under editor.api[name] and resolves descriptor-owned portals through editor.plugin(Plugin).
Core pluginsResolves core plugins, replaces core plugins with custom plugins that share the same name, and resolves the root plugin.
ComponentsMerges components into root-plugin component overrides.
Normalization guardWraps normalizeNode so editor.api.shouldNormalizeNode(entry) can skip a normalization pass.
Initial valueInitializes the value and selection through the runtime update path unless skipInitialization is true.

initialValue accepts a Plate value or a synchronous function that returns one. Load remote data before constructing the editor. Use the callback form when a decoder needs the compiled plugin model.

Core APIs

Core plugins are resolved before user plugins. Navigation Feedback is a React editor default and can be disabled with navigationFeedback: false. Its API uses the mounted editor returned by useEditor().

Methods

    Log a debug message when debug logging is enabled.

    Log an info message when the configured log level allows it.

    Log a warning when the configured log level allows it.

    Throw an EditorError by default in development. Configure DebugPlugin to change logging or throwErrors.

    Deserialize an HTML element into Plate nodes. The HTML parser plugin calls this for text/html paste data.

    Flash a live element in the calling mounted React view without a document or selection change.

    Clear this mounted view's feedback and return whether a target was active.

Core transactions

Mutations run through editor.update. Core Plate commands live on the transaction object, and plugins contribute their keyed commands through the constructor's update field.

Transforms

    Replace primary children, named roots, persisted meta, and optionally the selection through one configured Plate update.

    Insert a node or fragment through the Plate node transaction group.

    Update matching nodes through the Plate node transaction group.

    Toggle an inline mark through the Plate mark transaction group.

    Update the current selection through the Plate selection transaction group.

Plugin pipeline effects

Some core behavior is exposed by routing browser/editor events into the Plate transaction runtime rather than by adding public editor methods.

SurfaceEffect
Product codec registryCompiles constructor codec declarations created by context-bound defineCodecs(map) or defineCodecs(TargetPlugin, map), then delegates exact ContentSlice decoding and encoding to the generic clipboard runtime.
Plate change eventsEmits committed node and text change contexts through Plate on.nodeChange and on.textChange.
Plate React runtimeHandles editable keyboard, composition, focus, read-only, DOM selection export, and decoration refresh behavior.
HtmlPluginRegisters the text/html parser path and owns HTML element conversion through editor.api.html.deserialize.
BaseParagraphPluginRegisters the default paragraph element under name paragraph and maps HTML <p> elements, excluding code-font paragraphs.

Type helpers

Use ReturnType<typeof createBasicEditor> when another module needs the exact type returned by your editor factory. The installed plugin schema supplies the value type.

Typed editor helper
import type { ValueOf } from "platejs";
import { BoldPlugin, createEditor } from "platejs/react";
 
const BasicKit = [BoldPlugin] as const;
 
export const createBasicEditor = () => createEditor({ plugins: BasicKit });
 
type BasicEditor = ReturnType<typeof createBasicEditor>;
type BasicValue = ValueOf<BasicEditor>;
Typed editor helper
import type { ValueOf } from "platejs";
import { BoldPlugin, createEditor } from "platejs/react";
 
const BasicKit = [BoldPlugin] as const;
 
export const createBasicEditor = () => createEditor({ plugins: BasicKit });
 
type BasicEditor = ReturnType<typeof createBasicEditor>;
type BasicValue = ValueOf<BasicEditor>;
TypePurpose
EditorBroad editor type for framework boundaries.
ReturnType<typeof createBasicEditor>Exact editor type inferred from the factory's plugin tuple.
ValueOf<EditorType>Document value derived from that editor's compiled schema.

Related APIs

  • Plate components covers EditorRoot, EditorContent, EditorPreview, and component-layer runtime effects.
  • EditorController covers active, primary, and fallback editor lookup.
  • Plate plugin covers plugin definitions, methods, state, events, and render hooks.
  • Controlled Value covers React-owned value patterns around editor.update.