{"id":45396495,"url":"https://github.com/eigenpal/docx-js-editor","last_synced_at":"2026-02-26T16:22:03.705Z","repository":{"id":336598325,"uuid":"1147585130","full_name":"eigenpal/docx-js-editor","owner":"eigenpal","description":"WYSIWYG js DOCX editor","archived":false,"fork":false,"pushed_at":"2026-02-13T09:25:52.000Z","size":64525,"stargazers_count":367,"open_issues_count":8,"forks_count":10,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-02-13T16:10:21.317Z","etag":null,"topics":["docx","editor","js","wysiwyg"],"latest_commit_sha":null,"homepage":"https://docx-js-editor.vercel.app/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eigenpal.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-02T00:43:53.000Z","updated_at":"2026-02-13T10:01:45.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/eigenpal/docx-js-editor","commit_stats":null,"previous_names":["eigenpal/docx-js-editor"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/eigenpal/docx-js-editor","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eigenpal%2Fdocx-js-editor","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eigenpal%2Fdocx-js-editor/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eigenpal%2Fdocx-js-editor/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eigenpal%2Fdocx-js-editor/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eigenpal","download_url":"https://codeload.github.com/eigenpal/docx-js-editor/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eigenpal%2Fdocx-js-editor/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29689644,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T15:51:39.154Z","status":"ssl_error","status_checked_at":"2026-02-21T15:49:03.425Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docx","editor","js","wysiwyg"],"created_at":"2026-02-21T19:31:01.044Z","updated_at":"2026-02-21T19:31:01.660Z","avatar_url":"https://github.com/eigenpal.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/eigenpal/docx-js-editor\"\u003e\n    \u003cimg src=\"./assets/logo.png\" alt=\"DOCX JS Editor\" width=\"600\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@eigenpal/docx-js-editor\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@eigenpal/docx-js-editor.svg?style=flat-square\u0026color=00C853\" alt=\"npm version\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://www.npmjs.com/package/@eigenpal/docx-js-editor\"\u003e\u003cimg src=\"https://img.shields.io/npm/dm/@eigenpal/docx-js-editor.svg?style=flat-square\u0026color=00C853\" alt=\"npm downloads\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/eigenpal/docx-js-editor/blob/main/LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg?style=flat-square\u0026color=00C853\" alt=\"license\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://docx-js-editor.vercel.app/\"\u003e\u003cimg src=\"https://img.shields.io/badge/Live_Demo-00C853?style=flat-square\u0026logo=vercel\u0026logoColor=white\" alt=\"Live Demo\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# @eigenpal/docx-js-editor\n\nOpen-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/)\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://docx-js-editor.vercel.app/\"\u003e\n    \u003cimg src=\"./assets/editor.png\" alt=\"DOCX JS Editor screenshot\" width=\"500\" /\u003e\n  \u003c/a\u003e\n\u003c/p\u003e\n\nWe 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.\n\n### Framework Examples\n\n| Framework                                                                                                           | Example                                                                       |\n| ------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- |\n| \u003cimg src=\"https://vite.dev/logo.svg\" width=\"14\" /\u003e Vite + React                                                     | [`examples/vite`](examples/vite) ([demo](https://docx-js-editor.vercel.app/)) |\n| \u003cimg src=\"https://assets.vercel.com/image/upload/v1662130559/nextjs/Icon_dark_background.png\" width=\"14\" /\u003e Next.js | [`examples/nextjs`](examples/nextjs)                                          |\n| \u003cimg src=\"https://remix.run/favicon-192.png\" width=\"14\" /\u003e Remix                                                    | [`examples/remix`](examples/remix)                                            |\n| \u003cimg src=\"https://astro.build/favicon.svg\" width=\"14\" /\u003e Astro                                                      | [`examples/astro`](examples/astro)                                            |\n\n## Installation\n\n```bash\nnpm install @eigenpal/docx-js-editor\n```\n\n## Quick Start\n\n```tsx\nimport { useRef } from 'react';\nimport { DocxEditor, type DocxEditorRef } from '@eigenpal/docx-js-editor';\nimport '@eigenpal/docx-js-editor/styles.css';\n\nfunction Editor({ file }: { file: ArrayBuffer }) {\n  const editorRef = useRef\u003cDocxEditorRef\u003e(null);\n\n  const handleSave = async () =\u003e {\n    const buffer = await editorRef.current?.save();\n    if (buffer) {\n      await fetch('/api/documents/1', { method: 'PUT', body: buffer });\n    }\n  };\n\n  return (\n    \u003c\u003e\n      \u003cbutton onClick={handleSave}\u003eSave\u003c/button\u003e\n      \u003cDocxEditor ref={editorRef} documentBuffer={file} onChange={() =\u003e {}} /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n\u003e **Next.js / SSR:** The editor requires the DOM. Use a dynamic import or lazy `useEffect` load to avoid server-side rendering issues.\n\n## Props\n\n| Prop                    | Type                                        | Default           | Description                                       |\n| ----------------------- | ------------------------------------------- | ----------------- | ------------------------------------------------- |\n| `documentBuffer`        | `ArrayBuffer \\| Uint8Array \\| Blob \\| File` | —                 | `.docx` file contents to load                     |\n| `document`              | `Document`                                  | —                 | Pre-parsed document (alternative to buffer)       |\n| `readOnly`              | `boolean`                                   | `false`           | Read-only preview (hides toolbar, rulers, panel)  |\n| `showToolbar`           | `boolean`                                   | `true`            | Show formatting toolbar                           |\n| `showRuler`             | `boolean`                                   | `false`           | Show horizontal \u0026 vertical rulers                 |\n| `rulerUnit`             | `'inch' \\| 'cm'`                            | `'inch'`          | Unit for ruler display                            |\n| `showZoomControl`       | `boolean`                                   | `true`            | Show zoom controls in toolbar                     |\n| `showVariablePanel`     | `boolean`                                   | `true`            | Show template variable panel                      |\n| `variablePanelPosition` | `'left' \\| 'right'`                         | `'right'`         | Variable panel position                           |\n| `variableDescriptions`  | `Record\u003cstring, string\u003e`                    | —                 | Descriptions for template variables               |\n| `showPrintButton`       | `boolean`                                   | `true`            | Show print button in toolbar                      |\n| `showPageNumbers`       | `boolean`                                   | `true`            | Show page number indicator                        |\n| `enablePageNavigation`  | `boolean`                                   | `true`            | Enable interactive page navigation                |\n| `pageNumberPosition`    | `string`                                    | `'bottom-center'` | Position of page number indicator                 |\n| `showOutline`           | `boolean`                                   | `false`           | Show document outline sidebar (table of contents) |\n| `showMarginGuides`      | `boolean`                                   | `false`           | Show page margin guide boundaries                 |\n| `marginGuideColor`      | `string`                                    | `'#c0c0c0'`       | Color for margin guides                           |\n| `initialZoom`           | `number`                                    | `1.0`             | Initial zoom level                                |\n| `theme`                 | `Theme \\| null`                             | —                 | Theme for styling                                 |\n| `toolbarExtra`          | `ReactNode`                                 | —                 | Custom toolbar items appended to the toolbar      |\n| `placeholder`           | `ReactNode`                                 | —                 | Placeholder when no document is loaded            |\n| `loadingIndicator`      | `ReactNode`                                 | —                 | Custom loading indicator                          |\n| `className`             | `string`                                    | —                 | Additional CSS class name                         |\n| `style`                 | `CSSProperties`                             | —                 | Additional inline styles                          |\n| `onChange`              | `(doc: Document) =\u003e void`                   | —                 | Called on document change                         |\n| `onSave`                | `(buffer: ArrayBuffer) =\u003e void`             | —                 | Called on save                                    |\n| `onError`               | `(error: Error) =\u003e void`                    | —                 | Called on error                                   |\n| `onSelectionChange`     | `(state: SelectionState \\| null) =\u003e void`   | —                 | Called on selection change                        |\n| `onFontsLoaded`         | `() =\u003e void`                                | —                 | Called when fonts finish loading                  |\n| `onPrint`               | `() =\u003e void`                                | —                 | Called when print is triggered                    |\n| `onCopy`                | `() =\u003e void`                                | —                 | Called when content is copied                     |\n| `onCut`                 | `() =\u003e void`                                | —                 | Called when content is cut                        |\n| `onPaste`               | `() =\u003e void`                                | —                 | Called when content is pasted                     |\n\n## Ref Methods\n\n```tsx\nconst ref = useRef\u003cDocxEditorRef\u003e(null);\n\nawait ref.current.save(); // Returns ArrayBuffer of the .docx\nref.current.getDocument(); // Current document object\nref.current.setZoom(1.5); // Set zoom to 150%\nref.current.focus(); // Focus the editor\nref.current.scrollToPage(3); // Scroll to page 3\nref.current.print(); // Print the document\n```\n\n## Read-Only Preview\n\nUse `readOnly` for a preview-only viewer. This disables editing, caret, and selection UI.\n\n```tsx\n\u003cDocxEditor documentBuffer={file} readOnly /\u003e\n```\n\n## Plugins\n\nExtend 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:\n\n```tsx\nimport { DocxEditor, PluginHost, templatePlugin } from '@eigenpal/docx-js-editor';\n\nfunction Editor({ file }: { file: ArrayBuffer }) {\n  return (\n    \u003cPluginHost plugins={[templatePlugin]}\u003e\n      \u003cDocxEditor documentBuffer={file} /\u003e\n    \u003c/PluginHost\u003e\n  );\n}\n```\n\n| Plugin                                 | Description                                                                                  |\n| -------------------------------------- | -------------------------------------------------------------------------------------------- |\n| [Docxtemplater](src/plugins/template/) | Syntax highlighting and annotation panel for [docxtemplater](https://docxtemplater.com) tags |\n\nSee [docs/PLUGINS.md](docs/PLUGINS.md) for the full plugin API, including how to create custom plugins with panels, overlays, and ProseMirror integrations.\n\n## Features\n\n- Full WYSIWYG editing with Microsoft Word fidelity\n- Text and paragraph formatting (bold, italic, fonts, colors, alignment, spacing)\n- Tables, images, hyperlinks\n- Extensible plugin architecture\n- Undo/redo, find \u0026 replace, keyboard shortcuts\n- Print preview\n- Zero server dependencies\n\n## Development\n\n```bash\nbun install\nbun run dev          # Vite example on localhost:5173\nbun run dev:nextjs   # Next.js example on localhost:3000\nbun run dev:remix    # Remix example on localhost:3001\nbun run dev:astro    # Astro example on localhost:4321\n```\n\nEach example is independently deployable. Copy any `examples/\u003cframework\u003e/` directory to start your own project — just `npm install` and go.\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feigenpal%2Fdocx-js-editor","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feigenpal%2Fdocx-js-editor","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feigenpal%2Fdocx-js-editor/lists"}