TutorialMarch 10, 2026·2 min read

How to Add a DOCX Editor to Your React App

Step-by-step tutorial for integrating a full WYSIWYG DOCX editor into any React application using docx-js-editor. No server required — everything runs in the browser.

Why edit DOCX files in React?

Word documents are everywhere — contracts, invoices, reports, letters. If your app deals with documents, sooner or later users will ask to edit .docx files directly in the browser without downloading them, opening Word, and re-uploading.

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 takes a different approach: it parses OOXML on the client, renders it with ProseMirror, and exports back to .docx — all in the browser.

Prerequisites

You need a React project. Any framework works — Vite, Next.js, Remix, Astro — as long as it supports React components.

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>
  );
}

That's it. You now have a working DOCX editor in your React app.

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 specifics

If you're using Next.js, the editor must be loaded client-side since it relies on browser APIs:

import dynamic from "next/dynamic";
 
const DocxEditor = dynamic(
  () => import("@eigenpal/docx-js-editor").then((m) => m.DocxEditor),
  { ssr: false }
);

Also add transpilePackages to your next.config.ts:

const nextConfig = {
  transpilePackages: ["@eigenpal/docx-js-editor"],
};

What the editor supports

Out of the box you get:

  • 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

Full working examples with source code are available for each framework:

  • Vite example — the most feature-rich example with responsive zoom, mobile detection, and document name editing
  • Next.js example — dynamic import with SSR disabled, App Router setup
  • Remix example — lazy loading with Suspense fallback
  • Astro example — island architecture with client-side rendering

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

Next steps