Quickstart

Mount the headless engine and the DOM runtime.

This page mounts a minimal SpineEditor instance using @spine-editor/core and @spine-editor/dom.

Create an engine and runtime

import {
  branchNode,
  createEditorEngine,
  createPlanner,
  pos,
  textNode,
  textSelection,
  type EditorState,
  type NodeTypeName,
} from "@spine-editor/core";
import { createSpineDomRuntime } from "@spine-editor/dom";

const initialState: EditorState = {
  doc: {
    root: branchNode("doc" as NodeTypeName, [
      branchNode("paragraph" as NodeTypeName, [textNode("")]),
    ]),
  },
  selection: textSelection(pos(0), pos(0)),
  storedMarks: [],
  pluginState: {},
};

const engine = createEditorEngine({
  initialState,
  planner: createPlanner(),
});

const runtime = createSpineDomRuntime({
  engine,
  rootElement: document.getElementById("editor")!,
});

runtime.mount();

The runtime owns rendering, the substrate, the selection overlay, and clipboard/IME handling. The engine owns state and the pipeline.

What you get

  • Deterministic Intent → Plan → Transaction pipeline via EditorEngine.
  • Browser runtime translating events into intents.
  • Selection overlay with custom caret and per-line highlight rects.
  • Clipboard and IME integration.
  • Undo/redo via EditorEngine.undo() / .redo() backed by HistoryState.

Next steps