Installation

Install the DOCX editor in React or Vue. Add the stylesheet and set a client-only boundary for server-rendered apps.

Use one of these supported framework versions:

  • React ^18 || ^19
  • Vue ^3.3

Node version

To run the engine outside a browser, use Node ^20.16.0 || >=22.3.0.

Anything that measures text needs the text shaper. The shaper reaches Node builtins through process.getBuiltinModule, which arrived in Node 20.16.0 and 22.3.0. On an earlier version the shaper does not start. The engine then reports the Node version as the cause, rather than a missing binary.

This applies to server-side rendering, headless automation with @docx-editor.dev/editor-api, and build-time rendering. A browser-only app is unaffected.

The floor matters more than it looks. Measurement decides where lines wrap and pages break, so a shaper that cannot start is not a degraded mode. It changes your page count.

Pick a package

Each adapter declares the engine as a peer dependency. Install the engine and one adapter.

Use these commands to install the packages that your app needs:

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

The other packages are the same for both adapters:

# Tracked changes, comments, custom nodes
# EigenPal Pro License: https://www.docx-editor.dev/pricing
npm install @docx-editor.dev/pro

# Office.js-compatible editing API, on a server or with an active editor instance
# EigenPal Pro License: https://www.docx-editor.dev/pricing
npm install @docx-editor.dev/editor-api @docx-editor.dev/core

# Open-licensed substitutes for common Word fonts (optional)
npm install @docx-editor.dev/fonts

Mount the editor

Import the component and the stylesheet once. This example creates an empty document:

import { DocxEditor } from '@docx-editor.dev/react';
import '@docx-editor.dev/core/styles/editor.css';

export default function App() {
  return (
    <div style={{ height: '100vh' }}>
      <DocxEditor document="blank" />
    </div>
  );
}

Your app does not need Tailwind or an icon font.

document accepts an ArrayBuffer, Uint8Array, DocumentHandle, or 'blank'. Use 'blank' for an empty document. If you omit document, the editor stays idle until you pass document bytes.

Meet these layout requirements in both adapters:

  • Import the stylesheet to style the editor controls.
  • You do not need Tailwind because the precompiled CSS uses the .docx-editor scope.
  • Give the parent element a height because <DocxEditor> fills its parent.
  • A parent without a height collapses, so the editor does not appear.

Use server-rendered frameworks

The editor uses the Document Object Model (DOM) to measure text when it mounts. You must render the editor on the client. Vite apps need no extra boundary. Server-side rendering (SSR) frameworks need a client-only boundary.

Use the guide for your framework:

Fonts

The editor uses font bytes to measure line wraps and page breaks. It loads embedded document fonts without configuration. Some documents reference Word default fonts without embedding them. For these documents, @docx-editor.dev/fonts supplies open-licensed substitutes. Five families match advance widths. The Century Gothic substitute stays within 1% in the package fidelity check.

packagedFonts() supplies them per document: the editor calls it after parsing with the families that file declares. It loads a family when the document names it, or when that family is the document's default face, so a document pays for what it declares instead of all 20 eager faces. No request leaves your origin.

The default face counts because a run that names no font still has to be measured in one. That face is Calibri, so Carlito loads for every document.

import { DocxEditor, useFonts } from '@docx-editor.dev/react';
import { packagedFonts } from '@docx-editor.dev/fonts';

function Editor({ bytes }: { bytes: Uint8Array }) {
  const fonts = useFonts(packagedFonts());
  return <DocxEditor document={bytes} fonts={fonts} />;
}

packagedFonts() resolves after the document is parsed, so the first layout uses fixed measurement and the editor re-paginates when the faces arrive. Edits made in between survive that; the undo history behind them does not. For a document that must paginate correctly on the first pass, use defaultFonts() instead. For more information, see Fonts and measurement.

Edit documents without a browser

Use @docx-editor.dev/editor-api to edit a .docx without a browser. You can use it on a server, in a worker, or in a script. The package opens document bytes and uses an Office.js-compatible batching object model. It saves your changes as document bytes.

Next steps

On this page