Word fidelity
Word feature support matrix and fidelity guarantees for the open source DOCX editor: rendering, round-trip, security and API stability for adoption reviews.
Overview
- Client-side only. Parsing, rendering, editing, and serialization all run in the browser.
.docxin,.docxout. The editor reads OOXML and writes OOXML. Parts of the file it doesn't edit are carried over from the original archive unchanged.- Apache 2.0, all published packages. SemVer, with the public API tracked by generated snapshots in CI. React and Vue parity is a machine-checked contract.
- Commercial support: docx-editor@eigenpal.com.
Feature matrix
Every feature is tracked on three axes:
- Editing: can a user (or an AI agent) change it in the editor?
- Rendering: does it display the way Microsoft Word renders it?
- Round-trip: does it survive open, then save, unchanged?
A construct the editor doesn't model is preserved byte-for-byte and written back on save; that's the "Preserved" status below.
Legend: Full = works like Word · Partial = works with noted limits · Render only = displays correctly, not editable · Preserved = round-trips losslessly without rendering · Planned = on the roadmap · No = not supported.
Text & formatting
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Bold, italic, underline, strikethrough | Full | Full | Full | |
| Subscript & superscript | Full | Full | Full | |
| Font family & size | Full | Full | Full | Custom fonts registered via the fonts prop; theme fonts resolved from the OOXML theme. |
| Text color (RGB + theme colors) | Full | Full | Full | Theme color references (accent1...) are kept as references, not flattened to hex. |
| Highlight & shading | Full | Full | Full | Word highlight palette plus arbitrary w:shd fills. |
| Right-to-left & bidirectional text | Full | Full | Full | Bidi layout with mirrored alignment; Hebrew locale ships in @eigenpal/docx-editor-i18n. |
Paragraphs & styles
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Alignment & justification | Full | Full | Full | |
| Line & paragraph spacing | Full | Full | Full | |
| Indentation (incl. hanging indents) | Full | Full | Full | |
| Paragraph styles (Heading 1, Quote, custom styles) | Full | Full | Full | Style picker applies document styles, including custom styles with their numbering and indents. Defining new styles in the UI is not supported yet. |
| Paragraph borders & fills | Full | Full | Full | |
| Tab stops & leaders | Partial | Full | Full | Existing tab stops render (incl. right-tabs and dotted leaders in TOCs); a tab-stop editing UI is not built yet. |
Lists & numbering
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Bullet lists (multi-level) | Full | Full | Full | |
| Numbered lists (decimal, roman, letters) | Full | Full | Full | |
| Custom numbering definitions & style-linked numbering | Full | Full | Full | Numbering attached to custom paragraph styles resolves with Word’s precedence rules. |
| List continuation & restart | Full | Full | Full |
Tables
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Table insertion & cell editing | Full | Full | Full | |
| Row/column insert, delete, resize | Full | Full | Full | Resize commits Word-compatible twip widths. Agent-API table mutation is read-only for now. |
| Cell borders & shading | Full | Full | Full | |
| Merged cells (horizontal & vertical) | Full | Full | Full | |
| Tables split across pages | Full | Full | Full | Rows split mid-content with correct cut borders; vertically merged cells repaint on continuation pages like Word. |
| Nested tables | Full | Full | Full | |
| Table styles & conditional formatting (header row, banding) | Partial | Full | Full | cnfStyle conditional formatting renders and round-trips; switching table styles from the UI is not built yet. |
Images & drawings
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Inline images (paste, drag-drop, resize) | Full | Full | Full | |
| Floating images & wrap modes (square, topAndBottom...) | Full | Full | Full | Drag-to-reposition and edge resize with Word-style handles; text reflows around float zones. |
| WMF / EMF legacy vector images | Partial | Full | Full | Rendered via on-the-fly conversion (vector where possible, raster fallback) at the OOXML extent; the original WMF/EMF bytes are preserved on save. |
| Tracked image insert/delete | Full | Full | Full | |
| Text boxes & shapes | Partial | Partial | Full | Anchored text boxes render (incl. page-anchored letterhead shapes in headers); shape geometry editing is limited. |
Page layout, headers & footers
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| True pagination (Word-metric pages) | Full | Full | Full | The layout engine paginates like Word: page breaks, keep rules, split paragraphs marked across pages. |
| Sections (margins, size, orientation, per-section headers) | Partial | Full | Full | Margins editable; mid-body sectPr (section breaks) render and round-trip, inserting new sections from the UI is not built yet. |
| Headers & footers (edit in place) | Full | Full | Full | Same editing model as the body: tracked changes, fields, images and tables work inside headers/footers. |
| Watermarks (text & image) | Full | Full | Full | |
| Footnotes & endnotes | Full | Full | Full | Editable note bodies with auto-numbering; tracked changes work inside notes; note references inside tables paginate correctly. |
| Multi-column layout | No | Partial | Preserved | Column definitions are preserved on round-trip; rendering flows single-column today. |
Review: tracked changes, comments, notes
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Tracked changes (insert, delete, format) | Full | Full | Full | Full revision model incl. structural changes (paragraph breaks, paragraph props, table rows/cells). Opens cleanly in Word’s review pane. |
| Accept / reject changes (UI + API) | Full | Full | Full | Per-change and bulk accept/reject in the sidebar; headless acceptChangeById/rejectChangeById. Deliberately not exposed as agent tools: humans decide. |
| Comments (threads, replies, resolve) | Full | Full | Full | |
| AI redlining (agent-proposed tracked changes) | Full | Full | Full | Agents propose Word-native tracked changes via suggest_change; live in the editor, headless via DocxReviewer, or over MCP. |
Fields, links & TOC
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Hyperlinks (external) | Full | Full | Full | |
| Bookmarks & internal links | No | Partial | Full | Parsed and preserved losslessly; bookmark editing UI is deferred. |
| PAGE / NUMPAGES fields | Full | Full | Full | Insertable in headers/footers; values recompute as the layout paginates. |
| Table of contents | No | Full | Full | Existing TOCs render with tab leaders and working links; TOC regeneration is left to Word. |
| Other field codes (DATE, REF, MERGEFIELD...) | No | Partial | Preserved | Last-computed field results display; the field codes themselves round-trip untouched. |
Document structure & content controls
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Content controls (SDT): block, inline | Full | Full | Full | Addressable by tag/id/alias from the headless API; works inside footnotes too. |
| Repeating section controls | Full | Full | Full | |
| Dropdown, checkbox & date controls | Full | Full | Full | |
| Custom XML parts & data binding | No | No | Preserved | customXml parts and w:dataBinding round-trip byte-stable; no binding evaluation. |
| VBA macros & form fields (legacy) | No | No | Preserved | Never executed, by design (client-side security); the parts survive open -> save. |
Collaboration, i18n & editing UX
| Feature | Editing | Rendering | Round-trip | Notes |
|---|---|---|---|---|
| Realtime collaboration (Yjs) | Full | Full | Full | Live cursors, presence, comment sync, per-author tracked-change attribution. |
| Find & replace | Full | Full | Full | |
| Rich copy/paste (HTML clipboard) | Full | Full | Full | |
| Undo / redo | Full | Full | Full | |
| Editor UI in 9 languages | Full | Full | Full | en, de, fr, he, hi, pl, pt-BR, tr, zh-CN via @eigenpal/docx-editor-i18n. |
| AI agent toolkit (14 tools, 3 transports) | Full | Full | Full | Live editor bridge, headless DocxReviewer, MCP server; Word-JS-API-shaped. |
Rendering fidelity
The editor runs two renderers at once. A hidden ProseMirror instance owns the editing state (document, selection, undo history, keyboard and IME input) and is never shown. On every change, a layout painter rebuilds the visible pages from that state using Word's own metrics: twips, the document's fonts and themes, its section and margin geometry. The browser never decides where a line or page breaks; the painter does. The output doesn't drift from Word the way contenteditable editors drift, and it stays plain DOM text rather than a canvas bitmap.
The full comparison with contenteditable and canvas approaches is in Architecture. To judge fidelity yourself, open one of your own documents in the live demo next to Word.
The round-trip guarantee
A .docx file is a ZIP of XML parts, and Word writes a lot of XML the
editor has no reason to model: bookmarks, custom XML parts, mail-merge fields,
compatibility settings, VBA projects.
This editor's pipeline is parse → document model → edit → serialize. On
save it rewrites only the parts it changed (the body, plus headers, footers,
comments and notes when touched) and repacks every other part of the
original archive as-is: styles.xml, themes, the font table, settings,
media, relationships, custom XML. Concretely:
- Unmodeled XML elements and attributes are kept and re-emitted in place.
- Whole parts the editor never touches (custom XML, VBA projects, embedded fonts, OLE objects) are copied through the ZIP untouched.
- References stay intact: relationship IDs, bookmark names, field codes, style IDs and numbering definitions are not renamed or renumbered.
- Output is canonical OOXML, not merely valid: tracked changes are real
w:ins/w:delrevisions Word's review pane understands, theme colors stay theme references, numbering keeps its definitions.
How it's tested: a parity corpus of real documents is round-tripped in CI and compared structurally; serializer unit tests assert revision markup, conditional table formatting and section properties survive; 500+ Playwright tests drive the editor against Word-derived expectations.
What the guarantee is not: bit-identical files. The ZIP container is rebuilt and XML is re-serialized (whitespace can differ). The guarantee is semantic: nothing you didn't touch is lost or reinterpreted. A document that breaks this promise is a bug we want; attach it to a GitHub issue.
Security
- Documents never leave the browser. No upload endpoint, no server-side rendering service, no third-party conversion API.
- No macro execution. VBA macros and embedded code are never evaluated.
- AI integrations don't change this. With the agents toolkit, only tool-call text crosses the wire, to a route you own. There is no Eigenpal service in the path.
Bundle and performance
-coreships subpath exports that tree-shake independently.- ProseMirror packages are peers, never duplicated.
- Lazy-load the editor (
next/dynamic,React.lazy) to keep it out of the initial bundle. - The layout engine caches per-block measurements; an edit doesn't re-measure the document.
No published benchmarks; test with your own documents in the live demo.
Stability, license and support
- Apache 2.0, all packages. Contributions need a one-time CLA.
- SemVer via changesets; all packages share one version number.
- The public API is tracked by API Extractor snapshots; CI fails on drift.
- React/Vue parity is a checked contract;
agentPaneland controlledcommentsare still React-only. layout-engine,layout-painter,layout-bridgeandplugin-apiare@experimental.- Some advanced fidelity features may move to a commercial plan later; everything published stays Apache 2.0.
If a feature you need is Partial or missing, open an issue
with a sample .docx, or email docx-editor@eigenpal.com
for priority features and support contracts.
Next steps
- Quickstart: the load, edit, save loop
- Architecture: the dual-renderer design in depth
- Tracked changes: the review model in practice
- Migrating to 1.x if you're upgrading
Nuxt
Set up a Nuxt DOCX editor with the official module. One line in nuxt.config.ts gives you an auto-imported, SSR-safe DocxEditor component on Nuxt 3 and 4.
Examples
Runnable DOCX editor starters for Vite, Next.js, Remix, Astro, Vue, and Nuxt, plus collaboration and AI agent demos, and live in-page playgrounds.