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 2.x docs.

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.

Common alternatives include:

  • Server-side conversion: converts DOCX to HTML on the backend and converts the edited HTML back to DOCX. This process can omit unsupported formatting.
  • Proprietary SDKs: can require per-seat licenses and add large client bundles.
  • iframe embeds: limit interface customization and depend on a third-party service.

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. The following example creates 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. Parsing time depends on the document size, image data, and OOXML structure. For documents with many pages or 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:

The docxtemplater plugin example shows template variable processing.

Next steps