docx-editor 1.x has shipped. Vue support, i18n, agents.

Migration guide →
TutorialMarch 10, 20262 min read

How to Add a DOCX Editor to Your React App

Add a WYSIWYG DOCX editor to a React application with docx-js-editor. Install the package, load a .docx file, and save the edited document.

0.x postThis post uses the 0.x package names and APIs. For the current release see the 1.x docs and the migration guide.

Use case

If your React app handles contracts, invoices, reports, or letters, users may need to edit .docx files without downloading them, opening Word, and re-uploading the result.

Until recently, the only options were:

  • Server-side conversion: convert to HTML on the backend, lose formatting, convert back. Fragile and expensive to host.
  • Proprietary SDKs: lock-in, per-seat licensing, heavy bundles.
  • iframe embeds: limited control, no customization, dependent on third-party availability.

docx-js-editor parses OOXML on the client, renders it with ProseMirror, and exports back to .docx in the browser.

Prerequisites

You need a React project. Vite, Next.js, Remix, and Astro all work as long as the editor component renders on the client.

node --version   # v18 or later

Step 1: Install the package

npm install @eigenpal/docx-js-editor

Or with your preferred package manager:

# yarn
yarn add @eigenpal/docx-js-editor
 
# pnpm
pnpm add @eigenpal/docx-js-editor
 
# bun
bun add @eigenpal/docx-js-editor

Step 2: Create the editor component

The editor needs a .docx file as an ArrayBuffer. Here's a minimal component:

import { useState, useEffect } from "react";
import { DocxEditor } from "@eigenpal/docx-js-editor";
 
export function MyDocxEditor() {
  const [buffer, setBuffer] = useState<ArrayBuffer | null>(null);
 
  useEffect(() => {
    fetch("/sample.docx")
      .then((res) => res.arrayBuffer())
      .then(setBuffer);
  }, []);
 
  if (!buffer) return <p>Loading document...</p>;
 
  return (
    <div style={{ height: "80vh" }}>
      <DocxEditor
        documentBuffer={buffer}
        onSave={(blob) => {
          const url = URL.createObjectURL(blob);
          const a = document.createElement("a");
          a.href = url;
          a.download = "edited.docx";
          a.click();
          URL.revokeObjectURL(url);
        }}
      />
    </div>
  );
}

This mounts a DOCX editor and downloads the saved document from onSave.

Step 3: Handle file uploads

Let users upload their own documents:

function handleUpload(event: React.ChangeEvent<HTMLInputElement>) {
  const file = event.target.files?.[0];
  if (!file) return;
 
  const reader = new FileReader();
  reader.onload = () => {
    setBuffer(reader.result as ArrayBuffer);
  };
  reader.readAsArrayBuffer(file);
}

Add an upload button above the editor:

<input type="file" accept=".docx" onChange={handleUpload} />

Step 4: Next.js

Mark your component as 'use client':

"use client";
 
import { DocxEditor } from "@eigenpal/docx-js-editor";
import "@eigenpal/docx-js-editor/styles.css";
 
export function MyDocxEditor({ buffer }: { buffer: ArrayBuffer }) {
  return <DocxEditor documentBuffer={buffer} showToolbar />;
}

What the editor supports

Supported areas include:

  • Rich text formatting: bold, italic, underline, strikethrough, font size, font family, colors
  • Tables: cell merging, borders, column widths
  • Images: inline and floating image positioning
  • Page layout: headers, footers, page breaks, margins
  • Tracked changes: insertions, deletions, and formatting revisions with accept/reject
  • Comments: threaded document comments anchored to text ranges
  • Zoom control: zoom slider and page navigation
  • Document templates: variable placeholders via docxtemplater integration

Performance considerations

The editor parses OOXML directly in the browser. For typical business documents (1-20 pages), parsing takes under a second. For very large documents (100+ pages with many images), consider:

  1. Showing a loading spinner during parse
  2. Lazy-loading the editor component
  3. Compressing images before embedding

Framework examples

Working examples with source code are available for each framework:

There's also a docxtemplater plugin example showing template variable processing.

Next steps