Core

@docx-editor.dev/core

The framework-agnostic engine: OOXML read and write, the canonical document tree, layout, paint, and the Editor contract that adapters render.

This package is the engine. It reads a .docx into a canonical document tree, lays that tree out into pages, paints them, and writes the tree back to OOXML. It has no framework dependency and no UI.

Most apps never import it directly: @docx-editor.dev/react carries it. Import it when you are writing your own adapter, or when you need the contract types to type a function signature.

npm install @docx-editor.dev/core

Entry points

The root is the entry point for typical editor creation and typing: create an editor over bytes, the contract it implements, fonts, and the chrome registry. See the chrome slot reference for the complete registry vocabulary and its React and Vue toolbar parts.

import { createDocxEditor, loadFonts, WORD_DEFAULT_FONT } from '@docx-editor.dev/core';
import type { Editor, EditorSnapshot } from '@docx-editor.dev/core';

Import a subpath when you need the canonical tree, the layout pass, or the paint step directly.

SubpathContents
.Create an editor, the Editor contract, fonts, the chrome registry, the document model types.
./editorEverything the root re-exports, plus the paginated surface, ruler geometry, and module resolution.
./contracts/editorEditor, EditorCommand, EditorQuery, EditorSnapshot, DocumentSource, PageSetup, the contract an adapter renders.
./contracts/documentThe document-level edit and query vocabulary.
./contracts/typesDocument model types.
./contracts/modulesEditorModule, the shape @docx-editor.dev/pro implements.
./contracts/interactionSemantic addressing (SemanticTarget) and the InteractionOutcome that an attempt returns.
./storeThe canonical tree and its transactional store.
./layoutThe DOM-free layout pass.
./outputPaint: turning a laid-out document into page DOM, and the selection overlay over it.
./automationThe document object model behind @docx-editor.dev/editor-api.
./styles/editor.cssThe editor stylesheet. The packaged chrome and your own chrome both use it.

Prefer the root import. Use ./editor only when you build an adapter and need surface internals (the paginated surface, ruler geometry, module resolution).

The contract

Editor is the whole public surface an adapter uses. Call exec for commands. Call query and snapshot for reads:

import type { Editor, EditorSnapshot } from '@docx-editor.dev/core/contracts/editor';

function pageLabel(editor: Editor): string {
  const snapshot: EditorSnapshot = editor.snapshot();
  return `${snapshot.page.current} / ${snapshot.page.total}`;
}

snapshot() is version-cached: it returns the same reference until editor state changes, and its sub-objects are reference-stable. That is what makes useSyncExternalStore (and therefore useEditorState) correct without a deep compare on every store notification.

The pipeline

The pipeline has one direction:

bytes → bounded OPC/XML read → canonical document tree → layout → painted pages → serialize

The painted pages are the editable surface. There is no shadow document model to keep in sync with what you see.

Fidelity is structural. The canonical tree preserves XML content and package payloads pass through untouched. Content the engine cannot type (an unknown element, or a known one in an invalid position) becomes a generic node rather than being dropped, so unknown content never blocks editing and never disappears on save.

Untrusted input

A .docx is a zip of XML that whoever sent it fully controls. The engine sanitizes at the parse boundary (URL allowlisting, entity and zip-bomb limits, recursion and element caps, no zero-click external fetches, escaping on the way back out) so everything downstream receives an already-sanitized projection.

Anything you then render from document data (a font name, a hyperlink target, a comment body, a custom node's attributes) is still attacker-controlled at your boundary. Render it as text; do not build markup or URLs from it.

Next steps

  • Architecture: how the pipeline fits together
  • React: the adapter that renders this contract
  • Editing API: the object model over ./automation

On this page