Changelog
0.1.0
Minor Changes
-
3302af3: Initial public release.
@office-kit/docxis an OOXML-compliant (ECMA-376).docxgeneration and
editing library for browsers and Node.js. It ships as a single self-contained
package: the OPC, XML, and WordprocessingML layers are bundled in, not
published separately.@office-kit/docx-previewrenders anyDocxvalue as a
read-only DOM tree by wrapping the OSSdocx-previewrenderer.
The format is loosely based on Keep a Changelog
and the project adheres to Semantic Versioning.
Each user-visible change is also tracked via Changesets;
this file is a hand-curated overview.
Unreleased
Changed
-
No-classes API. Every package now exposes plain data types and
standalone functions instead of classes. The motivation is
tree-shaking: classes carry every method along with the prototype,
so a bundler can't drop unused operations once an instance escapes.Docxis aninterface(just{ opc, document, partName, … }).Docx.create(…)→createDocx(…).Docx.open(bytes)→openDocx(bytes).
Docx.fromBlob(blob)→fromBlob(blob).doc.appendParagraph(text)→appendParagraph(doc, text). Same
pattern for every previous method.- Previous getters become functions:
doc.paragraphs→paragraphs(doc),
doc.statistics→statistics(doc), etc. - Previous setters become
setXfunctions:doc.title = x→
setTitle(doc, x).doc.opc,doc.document,doc.partNamestay
as direct property access. OpcPackage,ContentTypesIndex,RelationshipSetare likewise
plain interfaces backed by standaloneaddPart,getPart,
allRelationships,packageRelationships, … functions.XmlParseErroris no longer a class. UseXmlParseError.is(e)for
narrowing (in place ofe instanceof XmlParseError).
A minimal
createDocx + appendParagraph + toUint8Arrayslice bundles
to ~42 KB minified; the full surface is ~131 KB. CI enforces both the
byte budget and that no feature-specific string literals from unused
branches leak into the minimal bundle (seescripts/check-tree-shake.mjs).
Added
@office-kit/docx— the publicDocxinterface and standalone-function API.
Ships as a single self-contained package; the layers below are bundled in
(src/internal/), not published separately:- OPC layer (
src/internal/opc) — Open Packaging Conventions
reader/writer with byte-stable round-trip for untouched parts, built on
fflate(OpcPackageinterface +readOpcPackage,writeOpcPackage,
addPart,getPart,allRelationships,packageRelationships, …). - XML layer (
src/internal/xml) — namespace-aware XML parser/serializer
that preserves attribute order, prefixes,xml:space="preserve", CDATA,
comments, and PIs. - WordprocessingML layer (
src/internal/wordprocessingml) — WML AST plus
parsers, writers, and builders for paragraphs, runs, tables, styles,
numbering, headers/footers, sections, comments, footnotes/endnotes,
hyperlinks, fields, and document properties.
- OPC layer (
@office-kit/docx-preview— browser-side read-only preview. Single function entry,
previewToDOM(source, container, options?) → Promise<Handle>. v0
implementation wraps the OSSdocx-preview(Apache-2.0). The wrap is
intentional and final; seedocs/PLAN-PREVIEW.mdfor the rationale.
Authoring (function API on @office-kit/docx)
- Lifecycle:
createDocx({ paragraphs? }),openDocx(bytes),
fromBlob(blob),toUint8Array(doc),toBlob(doc),clone(doc). - Paragraphs:
appendParagraph,insertParagraphAt,removeParagraph,
appendHeading,appendPageBreak,appendLineBreak,
appendSectionBreak,clearBody. - Inline / text:
replaceText,replaceTextEverywhere,findText,
findTextEverywhere,appendTextRun,setParagraphText,
paragraphText,setRunFormat,clearRunFormat,getRunFormat,
setParagraphAlignment,setParagraphIndent,setParagraphSpacing. - Styles + numbering:
addStyle,removeStyle,listStyles,
ensureHeadingStyles,addBulletList,addNumberedList,
applyListToParagraph. - Tables:
addTable,tables,removeTable,removeAllTables,
unwrapTable. - Images:
addImage,addImageRun,insertImageInto,images,
replaceImage,removeAllImages. - Headers / footers / sections:
addHeader,addFooter,
addPageNumberFooter,setPageSize,setPageMargins,
setPageOrientation,headers,footers,
removeAllHeaders,removeAllFooters. - Comments / footnotes / endnotes:
addComment,addFootnote,
addEndnote,removeAllComments,removeAllFootnotes,
removeAllEndnotes. - Hyperlinks + bookmarks:
addHyperlink,addInternalHyperlink,
externalHyperlinks,setHyperlinkUrl,removeAllHyperlinks,
addBookmark,removeBookmark,removeAllBookmarks,bookmarks. - Fields:
appendField,addTableOfContents,appendMergeField,
WORD_FIELDS, plus the page-number footer helper above. - Tracked changes:
acceptAllRevisions,rejectAllRevisions. - Core / app properties:
coreProperties,setCoreProperties,
appProperties,setAppProperties,title,author,
setTitle,setAuthor. - Templates (PowerPoint-style "open a designed base, append content"):
mergeStylesFromTemplate,findStyleIdByName,
setParagraphStyle,imageReferences,replaceImageByAltText. - Diagnostics:
validate(doc),statistics(doc),outline(doc),
fields(doc).
Browser preview (function API on @office-kit/docx-preview)
previewToDOM(source, container, options?)renders aDocx,
Uint8Array,Blob, orArrayBufferinto a DOM container.
Returns an idempotentHandle.dispose()for teardown.- Options:
classPrefix(default"wk-"),inWrapper,
breakPages,renderFonts,experimentalComments,
experimentalChanges. All overridable.
Build + tooling
tsdown(rolldown-based) replacestsupfor the bundling step.
Output extensions changed from.js/.d.tsto.mjs/.d.mts.pnpm testnow runspnpm buildfirst via the npm-standard
pretesthook so cross-package imports always resolve to fresh
dist.- New CI gate:
pnpm check:tree-shakebudgets a minimal
createDocx + appendParagraph + toUint8Arraybundle (~42 KB
minified) against the full surface (~131 KB). pnpm samplewrites 32 demonstration.docxfiles into
./samples/for manual verification in Microsoft Word.- New perf-smoke test catches accidental quadratic regressions:
10k-paragraph round-trip in 220 ms locally; budget is 10 s per
block to leave room for slow CI.
Implementation notes
- Lossless round-trip: every XML element the library does not yet structure
is preserved as aWmlRawBlock/WmlRawInlinepass-through with its
original child position, so re-saving an unmodified template leaves
Word's "needs repair" prompt out of the picture. - Verified against the mammoth.js fixture corpus (comments, footnotes,
endnotes, tables, images, hyperlinks, text boxes, UTF-8 BOM, lists)
and the python-docx test corpus. The ISO/IEC 29500 Strict variant is
explicitly out of scope today and remains pass-through only. - 512 tests, all running in vitest under Node 22 and 24; the public surface
also runs in modern browsers (no Node-only dependencies in the published
bundles). The browser-preview tests run under happy-dom (jsdom's
cross-realmUint8Arrayconfused fflate's type guards). - CI gate runs typecheck, lint, format check, tests across Node 22 / 24,
AND the tree-shake budget check. Node 20 was dropped from the matrix
after it reached end-of-life on 2026-04-30.