New

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

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.

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

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

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

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:

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

Next steps