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 laterStep 1: Install the package
npm install @eigenpal/docx-js-editorOr 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-editorStep 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:
- Showing a loading spinner during parse
- Lazy-loading the editor component
- 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
- Browse the source code on GitHub
- Try the live demo
- Read about building a document template system