Runtime and setup

Create server, browser, and collaborative runtimes; configure limits, save files, and release resources.

Create one runtime for each document host. Obtain document objects inside runtime.run(). The package requires the EigenPal Pro License.

Install and choose an entry

Install the API and its engine peer dependency:

npm install @docx-editor.dev/editor-api @docx-editor.dev/core

Your application must resolve one engine copy across the API and editor adapters. Server use requires Node.js ^20.16.0 || >=22.3.0.

EntryFactoriesResult
@docx-editor.dev/editor-apiDocxEditor.createServer, DocxEditor.createCollaborativePromise<DocxEditorServerRuntime>
@docx-editor.dev/editor-api/browserThe server factories and DocxEditor.createBrowserBrowser creation returns DocxEditorRuntime synchronously

Both entries export the document model and shared support types. CreateBrowserOptions belongs to the browser entry. DocxEditorNamespace describes each entry's factory object. These host factories are DocxEditor extensions, outside the Office.js document model.

Open, edit, and save bytes

This example replaces a unique template token and saves a separate file:

import { readFile, writeFile } from 'node:fs/promises';
import { DocxEditor } from '@docx-editor.dev/editor-api';

const runtime = await DocxEditor.createServer(await readFile('input.docx'), {
  author: 'Document agent',
});
try {
  await runtime.run(async (context) => {
    const matches = context.document.body.search('{{customer}}', {
      matchCase: true,
    });
    matches.load('items');
    await context.sync();
    if (matches.items.length !== 1) throw new Error('Expected one customer');
    matches.items[0]!.insertText('Ada', 'Replace');
    await context.sync();
  });
  await writeFile('output.docx', await runtime.save());
} finally {
  runtime.dispose();
}

createServer(bytes, options?) finishes parsing before its promise resolves. It does not retain the input byte array. save() returns a fresh, caller-owned Uint8Array each time. Mutating or transferring that array does not change the runtime. A detached runtime does not update an open editor automatically. Your application must explicitly load the saved bytes into that editor.

dispose() is safe to call more than once. Later calls to run() or save() fail with RuntimeDisposed. Disposal also invalidates tracked objects.

Drive an open browser editor

Pass an attached DocxEditorInstance from the core, React, or Vue editor integration:

import { DocxEditor } from '@docx-editor.dev/editor-api/browser';

const runtime = DocxEditor.createBrowser(editor, {
  author: 'Document reviewer',
});
try {
  await runtime.run(async (context) => {
    const first = context.document.paragraphs.getFirstOrNullObject();
    first.load('text');
    await context.sync();
    if (!first.isNullObject) first.font.bold = true;
    await context.sync();
  });
} finally {
  runtime.dispose();
}

Browser edits use the editor's transaction and Undo history. The browser runtime has no save() method. Save through the owning editor. Runtime disposal releases its adapter; it does not destroy the editor.

Configure a host

OptionHostsMeaning
authorAllAuthor name for comment creation, replies, and tracked text edits
revisionTextViewAllallMarkup by default; original hides pending insertions and retains pending deletions in text reads and search
limitsServer and collaborativeBounded ZIP, XML, part, and relationship parsing
paginationServer and collaborativeExplicit measured pagination for page-field result updates
modulesServer and collaborativeEditorModule[] contributions for the DOM-free host

CreateCollaborativeOptions uses CreateServerOptions. ServerPaginationOptions accepts a required measurer and optional producer. See Fields and pagination for font resources and cleanup. EditorModule exposes id and optional collaboration; it does not install browser UI.

createCollaborative(bytes, collaboration, options?) uses an existing EditorCollaborationSession. The collaboration transport and session belong to your application. See Collaboration for a complete shared review workflow. Do not treat detached server edits as collaborative writes.

Inspect capabilities and dynamic permissions

Read runtime.capabilities or context.capabilities without calling load(). The DocumentCapabilities object remains frozen for the runtime's lifetime.

CapabilityServerBrowser
documentYesRequires a document when the host reports capabilities
saveYesNo
eventsYesYes
selection, scrolling, layoutNoYes

Explicit server pagination does not give a server a browser selection or layout surface. The events flag does not provide a public event subscription API on the runtime. Capabilities do not guarantee write permission. Browser review writes also require the Pro review module and an editable document. Handle errors from the call or sync().

Bound input parsing

DocumentLimits has optional zip, xml, maxXmlParts, and maxRelationships fields. DocumentZipLimits requires maxEntries and maxTotalBytes; maxRatio is optional. DocumentXmlLimits requires maxBytes; maxElements is optional. Counts and byte budgets must be finite nonnegative integers. Compression ratios can be fractional.

The default XML element budget is 10,000,000 per part. The engine limits each XML part to 50,000,000 elements, 64 MiB, and 256 nested levels. These limits do not guarantee sufficient host memory. Malformed input or invalid limits produce InvalidArgument. An exceeded budget produces ResourceLimitExceeded with a limit field. See Batching, loading, and errors for recovery.

Next steps

On this page