https://github.com/eigenpal/docx-js-editor
WYSIWYG js DOCX editor
https://github.com/eigenpal/docx-js-editor
docx editor js wysiwyg
Last synced: 3 months ago
JSON representation
WYSIWYG js DOCX editor
- Host: GitHub
- URL: https://github.com/eigenpal/docx-js-editor
- Owner: eigenpal
- License: mit
- Created: 2026-02-02T00:43:53.000Z (4 months ago)
- Default Branch: main
- Last Pushed: 2026-02-13T09:25:52.000Z (4 months ago)
- Last Synced: 2026-02-13T16:10:21.317Z (4 months ago)
- Topics: docx, editor, js, wysiwyg
- Language: TypeScript
- Homepage: https://docx-js-editor.vercel.app/
- Size: 61.5 MB
- Stars: 367
- Watchers: 1
- Forks: 10
- Open Issues: 8
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# @eigenpal/docx-js-editor
Open-source WYSIWYG DOCX editor for React. Open, edit, and save `.docx` files entirely in the browser — no server required. [Try the live demo.](https://docx-js-editor.vercel.app/)
We built it for ourselves in [eigenpal.com](https://eigenpal.com) in order to have an editor for `.docx` files, which serve as AI document workflow output templates for our clients.
### Framework Examples
| Framework | Example |
| ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |
|
Vite + React | [`examples/vite`](examples/vite) ([demo](https://docx-js-editor.vercel.app/)) |
|
Next.js | [`examples/nextjs`](examples/nextjs) |
|
Remix | [`examples/remix`](examples/remix) |
|
Astro | [`examples/astro`](examples/astro) |
## Installation
```bash
npm install @eigenpal/docx-js-editor
```
## Quick Start
```tsx
import { 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(null);
const handleSave = async () => {
const buffer = await editorRef.current?.save();
if (buffer) {
await fetch('/api/documents/1', { method: 'PUT', body: buffer });
}
};
return (
<>
Save
{}} />
>
);
}
```
> **Next.js / SSR:** The editor requires the DOM. Use a dynamic import or lazy `useEffect` load to avoid server-side rendering issues.
## Props
| Prop | Type | Default | Description |
| ----------------------- | ------------------------------------------- | ----------------- | ------------------------------------------------- |
| `documentBuffer` | `ArrayBuffer \| Uint8Array \| Blob \| File` | — | `.docx` file contents to load |
| `document` | `Document` | — | Pre-parsed document (alternative to buffer) |
| `readOnly` | `boolean` | `false` | Read-only preview (hides toolbar, rulers, panel) |
| `showToolbar` | `boolean` | `true` | Show formatting toolbar |
| `showRuler` | `boolean` | `false` | Show horizontal & vertical rulers |
| `rulerUnit` | `'inch' \| 'cm'` | `'inch'` | Unit for ruler display |
| `showZoomControl` | `boolean` | `true` | Show zoom controls in toolbar |
| `showVariablePanel` | `boolean` | `true` | Show template variable panel |
| `variablePanelPosition` | `'left' \| 'right'` | `'right'` | Variable panel position |
| `variableDescriptions` | `Record` | — | Descriptions for template variables |
| `showPrintButton` | `boolean` | `true` | Show print button in toolbar |
| `showPageNumbers` | `boolean` | `true` | Show page number indicator |
| `enablePageNavigation` | `boolean` | `true` | Enable interactive page navigation |
| `pageNumberPosition` | `string` | `'bottom-center'` | Position of page number indicator |
| `showOutline` | `boolean` | `false` | Show document outline sidebar (table of contents) |
| `showMarginGuides` | `boolean` | `false` | Show page margin guide boundaries |
| `marginGuideColor` | `string` | `'#c0c0c0'` | Color for margin guides |
| `initialZoom` | `number` | `1.0` | Initial zoom level |
| `theme` | `Theme \| null` | — | Theme for styling |
| `toolbarExtra` | `ReactNode` | — | Custom toolbar items appended to the toolbar |
| `placeholder` | `ReactNode` | — | Placeholder when no document is loaded |
| `loadingIndicator` | `ReactNode` | — | Custom loading indicator |
| `className` | `string` | — | Additional CSS class name |
| `style` | `CSSProperties` | — | Additional inline styles |
| `onChange` | `(doc: Document) => void` | — | Called on document change |
| `onSave` | `(buffer: ArrayBuffer) => void` | — | Called on save |
| `onError` | `(error: Error) => void` | — | Called on error |
| `onSelectionChange` | `(state: SelectionState \| null) => void` | — | Called on selection change |
| `onFontsLoaded` | `() => void` | — | Called when fonts finish loading |
| `onPrint` | `() => void` | — | Called when print is triggered |
| `onCopy` | `() => void` | — | Called when content is copied |
| `onCut` | `() => void` | — | Called when content is cut |
| `onPaste` | `() => void` | — | Called when content is pasted |
## Ref Methods
```tsx
const ref = useRef(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 document
```
## Read-Only Preview
Use `readOnly` for a preview-only viewer. This disables editing, caret, and selection UI.
```tsx
```
## Plugins
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:
```tsx
import { DocxEditor, PluginHost, templatePlugin } from '@eigenpal/docx-js-editor';
function Editor({ file }: { file: ArrayBuffer }) {
return (
);
}
```
| Plugin | Description |
| -------------------------------------- | -------------------------------------------------------------------------------------------- |
| [Docxtemplater](src/plugins/template/) | Syntax highlighting and annotation panel for [docxtemplater](https://docxtemplater.com) tags |
See [docs/PLUGINS.md](docs/PLUGINS.md) for the full plugin API, including how to create custom plugins with panels, overlays, and ProseMirror integrations.
## Features
- 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
## Development
```bash
bun install
bun run dev # Vite example on localhost:5173
bun run dev:nextjs # Next.js example on localhost:3000
bun run dev:remix # Remix example on localhost:3001
bun run dev:astro # Astro example on localhost:4321
```
Each example is independently deployable. Copy any `examples//` directory to start your own project — just `npm install` and go.
## License
MIT