Office.js compatibility
Compare the supported Word JavaScript API subset, known differences, and unavailable APIs.
@docx-editor.dev/editor-api implements a subset of the Word JavaScript API object model.
You can reuse code based on objects such as Document, Body, Paragraph, and Range.
You must replace the Office host setup. You must also account for the differences on this page.
Compatibility matrix
Supported subset means that the listed objects and operations work. It does not mean that every Office.js member in that area works.
| Area | Status | Implemented | Limits |
|---|---|---|---|
| Batches and object lifecycle | Supported subset | load(), sync(), context.trackedObjects, isNullObject, and null-object accessors | Item accessors need one extra sync(). Navigation expansion does not work. |
| Document and body | Supported subset | Document.body, paragraphs, comments, revisions, sections, content controls, body text, styles, search, clear, and insertion | The package does not provide Office.onReady or Word.run. |
| Paragraphs and ranges | Supported subset | Read text, insert or replace text, insert paragraphs, clear, delete, split, search, style, hyperlinks, and selection | The API does not expose document-wide start or end offsets. |
| Search | Partial | Plain-text search, matchCase, and matchWholeWord | ignorePunct, ignoreSpace, and matchWildcards compile but refuse true with NotSupported. |
| Font formatting | Partial | bold, italic, color, name, and size | underline and Office.js highlightColor do not exist. Mixed, unspecified, or inherited style values return null. |
| Paragraph formatting | Supported subset | Style, alignment, first-line indent, left indent, right indent, line spacing, space before, and space after | The API exposes these values on Paragraph. It does not expose the full ParagraphFormat object. |
| Lists | Partial | List discovery, list paragraphs, levels, and paragraph insertion | The API does not expose list marker text, sibling indexes, or picture levels. |
| Bookmarks | Partial | Discover bookmarks, read names and ranges, and select bookmarks | The API does not support bookmark deletion or document-wide bookmark offsets. |
| Sections and page setup | Partial | Section bodies, headers, footers, page size, orientation, and margins | A missing header or footer returns ItemNotFound. A read never creates a part. |
| Footnotes and endnotes | Supported subset | Enumerate notes, read note bodies and text, move to the next note, and delete notes | Use document.footnotes and document.endnotes. These accessors differ from Office.js. |
| Comments and replies | Partial | Read, create, reply, resolve, delete, and get the comment range | Writes need an explicit author. Browser writes also need the Pro review module and an editable document. Comment body replacement does not work. |
| Tracked changes | Partial | Read actionable revisions, get their ranges, and accept or reject one revision or all revisions | The collection omits unsupported structural revision types. A collection-wide decision refuses the full batch if unsupported markup remains. |
| Content controls | Partial | Common properties, nested controls, lookup by id, tag, or title, text insertion, deletion, ranges, and typed value writes | The API does not expose typed Office.js subtype objects. Writes to custom XML-bound controls refuse. |
| Hyperlinks | Partial | Read or write Range.hyperlink | Standalone Hyperlink and HyperlinkCollection objects do not exist. |
| Tables | Unavailable | The editor can display tables | The editing API does not expose Table, TableCollection, or TableCell. |
| Images and shapes | Unavailable | The editor can display supported document graphics | The editing API does not expose InlinePicture, picture list levels, Shape, or canvases. |
Differences that affect existing code
| Office.js behavior | DocxEditor behavior | Required change |
|---|---|---|
Office.onReady and Word.run open a batch. | Your application creates a server or browser runtime. | Use DocxEditor.createServer(bytes) or DocxEditor.createBrowser(editor). |
| An item accessor returns a usable proxy immediately. | getFirst(), getLast(), and null-object forms resolve after sync(). | Add one sync() before you load or change the returned object. |
A collection can load item properties with paths such as items/text. | A collection loads its items only. | Load the collection, sync, load each item, then sync again. |
LoadQueryOptions.expand loads navigation properties. | A non-empty expand value throws InvalidArgument. | Load each navigation object or collection directly. |
sync() can return a pass-through value. | sync() returns Promise<void>. | Keep pass-through values in local state. |
| The Office host supplies the signed-in comment author. | DocxEditor has no ambient account identity. | Pass { author } when you create the runtime. |
Comment and revision dates have the Date type. | Invalid or missing file dates return null. | Narrow the nullable Date before you use it. |
| Font reads use concrete values. | Mixed, unspecified, or inherited style values return null. | Narrow the value before you reuse it in a write. |
Range.select() runs inside Word. | Selection needs an attached browser editor. | Check runtime.capabilities.selection. A server runtime returns NotSupported. |
| Header and footer getters can create missing parts. | Getters only return existing or inherited parts. | Handle ItemNotFound when no part exists. |
ContentControl.id is a number. | ContentControl.id is a string because DOCX ids can be missing or repeated. | Do not use the file id as a unique numeric key. |
ContentControl.subtype uses Word interface terms. | ContentControl.subtype uses DOCX control terms. | Handle values such as plainText, dropDownList, and checkbox. |
The extra item-accessor sync looks like this:
const results = context.document.body.search('Total');
await context.sync();
const first = results.getFirst();
await context.sync();
first.insertText('TOTAL', 'Replace');
await context.sync();Common DocxEditor additions
These common members extend the Office.js-shaped subset.
| Member | Purpose |
|---|---|
Body.bookmarks | Enumerates bookmarks in one body story. |
Body.revisions | Enumerates revisions in one body story. |
Document.footnotes and Document.endnotes | Enumerate document notes. |
NoteItem.text | Reads the same plain text as note.body.text. |
ContentControlCollection.getByTag() and getByTitle() | Finds controls without a file id. |
ContentControl.setValue() | Writes values for text, checkbox, date, and list controls. |
ContentControl.isBound | Reports whether custom XML binding exists. |
ContentControl.subtype | Reports the control type with DOCX terms. |
Comment.text and CommentReply.text | Read comment text without replacing the comment body. |
Paragraph.uniqueLocalId | Reads the paragraph identity for the active runtime. |
Body.bookmarks and Body.revisions only cover that body's story.
They do not combine the main body, headers, footers, and notes.
ContentControl.isBound is a preflight check.
sync() checks the binding again before it applies a write.
APIs that do not exist
Code that uses these APIs fails during TypeScript compilation.
| API | Available alternative |
|---|---|
Table, TableCollection, TableCell | No editing API alternative. |
InlinePicture, picture list levels | No editing API alternative. |
Shape and canvases | No editing API alternative. |
| Repeating-section and picture content-control objects | Use common ContentControl members for other control kinds. |
ContentControl.xmlMapping | Use ContentControl.isBound to detect a binding. Bound writes still refuse. |
Hyperlink, HyperlinkCollection | Use Range.hyperlink for one range. |
Body.getHtml(), Body.getOoxml(), Paragraph.getText() | Load Body.text or Paragraph.text. No OOXML or HTML result exists. |
BookmarkCollection.exists() | Load the collection and inspect its items. |
Font.underline, Office.js Font.highlightColor | No editing API alternative. |
Range.start, Range.end, Bookmark.start, Bookmark.end | Use ranges and paragraph text. |
Migrate an add-in
- Replace
Word.run()with a runtime fromDocxEditor.createServer()orDocxEditor.createBrowser(). - Keep the existing
load()andsync()pattern. - Add the extra syncs listed in Differences that affect existing code.
- Check the compatibility matrix for every object your add-in uses.
- Handle typed refusals such as
NotSupported,NotImplemented, andItemNotFound.
How compatibility is checked
The repository keeps a reviewed manifest of supported Word API symbols.
CI compares the authored TypeScript declarations with a pinned @types/office-js reference.
CI also compiles representative Word code against the DocxEditor declarations.
The package does not include Microsoft's declarations. Installation, tests, and builds do not fetch them.
Next steps
Overview
Office.js-compatible editing API: an object model that batches its work, running on a server over bytes or in a page against an editor already open.
@docx-editor.dev/core
The framework-agnostic engine: OOXML read and write, the canonical document tree, layout, paint, and the Editor contract that adapters render.