Core API
Programmatic DOCX import and export without mounting an editor.
@portone/docx-editor/core provides programmatic DOCX import and export without mounting an
editor. It returns a ProseMirror document together with an opaque session that retains the rest of
the DOCX package.
Import and export
Keep the session returned by importDocx and pass it back to exportDocx with the original or
transformed document:
import { exportDocx, importDocx } from "@portone/docx-editor/core";
const { doc, session } = importDocx(source);
const bytes = exportDocx(doc, session);The core functions accept an ArrayBuffer or Uint8Array. The React component also accepts a
Blob or File and reads it before import.
The session belongs to the imported document and must not be constructed or modified by consumers.
Use documentNumbering(session) and documentPartPath(session) for the package information
exposed by the public API.
Server environments
Browsers provide the DOMParser and Node globals used during import. A server must install
compatible implementations before calling importDocx:
import { JSDOM } from "jsdom";
const { window } = new JSDOM();
globalThis.DOMParser = window.DOMParser;
globalThis.Node = window.Node;Use a parser configuration that disables external entities and external fetching.
This works without friction on a long-running Node server. On serverless functions jsdom adds noticeable bundle weight and cold-start time, and edge runtimes cannot run it at all, so treat those environments as unsupported for now.
Errors
DocxImportError and DocxExportError expose stable code values for application handling. Error
messages are intended for developers and may be reworded.
import { DocxImportError, importDocx } from "@portone/docx-editor/core";
try {
importDocx(source);
} catch (error) {
if (error instanceof DocxImportError) {
console.error(error.code);
}
throw error;
}Both classes are exported from the root entry as well, so a React screen can switch on the same codes without importing the core entry.
Import codes
| Code | Why the document was refused |
|---|---|
not-a-docx | The bytes are not a readable zip container, its entry names are not a package's, or an entry does not hold what it claims to. |
too-large | The package asks to inflate beyond the limits below. |
missing-part | The package carries no main document part. |
missing-body | The main part carries no body. |
malformed-xml | The XML cannot be parsed, declares a DTD, or its markup is inconsistent. |
unsupported-content | The document holds markup that could not be written back out unchanged. |
A file a person picked can fail with any of these, so the code is worth showing: not-a-docx and
too-large are usually the person's to fix, while the rest describe the file itself.
Export codes
| Code | Why the document could not be written |
|---|---|
missing-numbering-part | A new list needs a numbering part the document does not have. |
missing-content-types | A new image needs a content types part the package does not have. |
unsupported-content | The document holds a node kind with no way to serialize it. |
lost-original | A node that carries only its original XML has lost it. |
malformed-xml | An original XML fragment cannot be read well enough to rewrite. |
invalid-table | The table grid is inconsistent, such as a vertical merge outliving its rows. |
An export failure leaves the editor state untouched, so a screen can report the reason and let the
person carry on editing.
missing-numbering-part is the one an ordinary edit can reach: a document with no numbering part
cannot take a new list, and the built-in list controls report that they do not apply for exactly
that reason.
In the React component
The component renders a refusal in place of the editor when import fails, either through
renderImportError or through the built-in panel, which turns each import code into a sentence.
Only DocxImportError becomes a rendered refusal; anything else, a Blob that could not be read
included, is thrown for an error boundary above to take.
On the way out, downloadDocx and exportBytes rethrow DocxExportError as it is.
Import limits
- A single inflated part is limited to 32 MiB and the package total to 64 MiB.
- Package paths that escape the archive and XML containing a DTD are rejected.
- An image over 16 MiB is retained in the package without being rendered by the editor.
Utilities
The core entry exports the document schema (docxSchema), the numbering reader
(parseNumbering), typed format readers such as toRunFormat and toParagraphFormat, and the
unit conversions emuToPx and pxToEmu used for programmatic transforms. The published
TypeScript declarations describe the complete surface.