Open-source WYSIWYG DOCX editor for React. Open, edit, and save .docx files entirely in the browser — no server required. Try the live demo.
npm install @eigenpal/docx-js-editorimport { useRef } from 'react';
import { DocxEditor, type DocxEditorRef } from '@eigenpal/docx-js-editor';
import '@eigenpal/docx-js-editor/styles.css';
function Editor({ file }: { file: ArrayBuffer }) {
const editorRef = useRef<DocxEditorRef>(null);
const handleSave = async () => {
const buffer = await editorRef.current?.save();
if (buffer) {
await fetch('/api/documents/1', { method: 'PUT', body: buffer });
}
};
return (
<>
<button onClick={handleSave}>Save</button>
<DocxEditor ref={editorRef} documentBuffer={file} onChange={() => {}} />
</>
);
}Next.js / SSR: The editor requires the DOM. Use a dynamic import or lazy
useEffectload to avoid server-side rendering issues.
| Prop | Type | Default | Description |
|---|---|---|---|
documentBuffer |
ArrayBuffer |
— | .docx file contents to load |
document |
Document |
— | Pre-parsed document (alternative to buffer) |
readOnly |
boolean |
false |
Read-only preview (no caret/selection) |
showToolbar |
boolean |
true |
Show formatting toolbar |
showRuler |
boolean |
false |
Show horizontal ruler |
showZoomControl |
boolean |
true |
Show zoom controls |
showVariablePanel |
boolean |
true |
Show template variable panel |
initialZoom |
number |
1.0 |
Initial zoom level |
onChange |
(doc: Document) => void |
— | Called on document change |
onSave |
(buffer: ArrayBuffer) => void |
— | Called on save |
onError |
(error: Error) => void |
— | Called on error |
const ref = useRef<DocxEditorRef>(null);
await ref.current.save(); // Returns ArrayBuffer of the .docx
ref.current.getDocument(); // Current document object
ref.current.setZoom(1.5); // Set zoom to 150%
ref.current.focus(); // Focus the editor
ref.current.scrollToPage(3); // Scroll to page 3
ref.current.print(); // Print the documentUse readOnly for a preview-only viewer. This disables editing, caret, and selection UI.
<DocxEditor documentBuffer={file} readOnly />Extend the editor with the plugin system. Wrap DocxEditor in a PluginHost and pass plugins that can contribute ProseMirror plugins, side panels, document overlays, and custom CSS:
import { DocxEditor, PluginHost, templatePlugin } from '@eigenpal/docx-js-editor';
function Editor({ file }: { file: ArrayBuffer }) {
return (
<PluginHost plugins={[templatePlugin]}>
<DocxEditor documentBuffer={file} />
</PluginHost>
);
}See docs/PLUGINS.md for the full plugin API, including how to create custom plugins with panels, overlays, and ProseMirror integrations.
- Full WYSIWYG editing with Microsoft Word fidelity
- Text and paragraph formatting (bold, italic, fonts, colors, alignment, spacing)
- Tables, images, hyperlinks
- Extensible plugin architecture
- Undo/redo, find & replace, keyboard shortcuts
- Print preview
- Zero server dependencies
MIT