New

docx-editor 1.x has shipped. Vue support, i18n, agents. Read the migration guide →

Packages

@eigenpal/docx-editor-core

Framework-agnostic core: document tree, OOXML parser/serializer, ProseMirror schema, plugin contract. Underlies both the React and Vue adapters.

What's in it

The document tree, the OOXML parser and serializer, the ProseMirror schema, layout primitives, the plugin contract. No DOM, no framework. The React and Vue adapters depend on it. You install -core directly only when you don't want an editor UI on the page.

npm install @eigenpal/docx-editor-core

When to use it directly

  • Server-side .docx processing: parse buffer, walk the tree, mutate, serialize back out.
  • Headless extraction: pull text, tables, headers/footers without rendering.
  • Custom renderer or DOM bridge against the shared schema.
  • Plugins that need to work in React, Vue, and headless contexts. Use the core-plugins subpath.

If you want an actual editor in a React or Vue app, install @eigenpal/docx-editor-react or @eigenpal/docx-editor-vue. Both pull -core in transitively, so you don't need it as a separate dep.

Subpaths

61 published subpaths. The ones you'll touch most:

  • @eigenpal/docx-editor-core: root barrel
  • @eigenpal/docx-editor-core/docx-parser: parseDocx(buffer)Document tree
  • @eigenpal/docx-editor-core/docx-serializer: Document.docx buffer
  • @eigenpal/docx-editor-core/types: Document, Paragraph, Run, Insertion, Deletion, Comment
  • @eigenpal/docx-editor-core/core-plugins: plugin contract for non-React, non-Vue hosts
  • @eigenpal/docx-editor-core/headless: bridge-shaped APIs (no DOM)

All 61 are in the API reference.

Parse, mutate, serialize

import { parseDocx } from "@eigenpal/docx-editor-core/docx-parser";
import { serializeDocx } from "@eigenpal/docx-editor-core/docx-serializer";
 
const buffer = await fetch("./document.docx").then((r) => r.arrayBuffer());
const tree = await parseDocx(buffer);
 
for (const para of tree.body) {
  if (para.type === "paragraph") {
    console.log(para.paraId, para.runs.map((r) => r.text).join(""));
  }
}
 
const out = await serializeDocx(tree);

The tree shape is the same the editor renders against. Anything you build against -core ports without translation when the same buffer reaches the live editor.

Where to next