Skip to content

Repository files navigation

@office-kit/docx

OOXML-compliant (ECMA-376) .docx generation library. Runs in modern browsers and Node.js.

  • Build a Word document from scratch with a programmatic API.
  • Open an existing .docx as a template, edit it, and serialize it back.
  • Target: full WordprocessingML coverage of ECMA-376 Part 1.

Status: pre-1.0. Core functionality (openDocx / createDocx / toUint8Array) is stable; details may shift before v1. See CLAUDE.md for engineering principles and scope rules and PLAN.md for the milestone roadmap.

Install

pnpm add @office-kit/docx
# or: npm install @office-kit/docx / yarn add @office-kit/docx

@office-kit/docx ships ESM-only with bundled .d.ts types. It has no Node-only dependencies and works in browsers (including with the Blob and File APIs).

Quick start

import{addBulletList,addTable,appendParagraph,createDocx,openDocx,PAGE_SIZE_A4,replaceTextEverywhere,setPageSize,toUint8Array,}from"@office-kit/docx";// From scratchconstdoc=createDocx({paragraphs: ["Hello, world."]});appendParagraph(doc,"Bullets:");addBulletList(doc,["one","two","three"]);addTable(doc,[["Name","Score"],["Alice","90"],]);setPageSize(doc,PAGE_SIZE_A4);constbytes=toUint8Array(doc);// From an existing .docx templateconsttpl=openDocx(existingDocxBytes);replaceTextEverywhere(tpl,/\{\{(\w+)\}\}/g,(m)=>values[m.captures[0]!]??"");constout=toUint8Array(tpl);

Why standalone functions instead of methods? Each operation is its own export, so a bundler can tree-shake any function you don't import. A minimal createDocx + appendParagraph + toUint8Array slice bundles to ~42 KB minified; the full surface is ~131 KB. CI enforces both numbers.

See docs/examples.md for the full API walkthrough (images, comments, footnotes, headers/footers, bookmarks, hyperlinks, tracked changes, core document properties).

Browser preview

Pair @office-kit/docx with @office-kit/docx-preview to render any Docx value as a read-only DOM tree:

import{openDocx}from"@office-kit/docx";import{previewToDOM}from"@office-kit/docx-preview";constdoc=openDocx(bytes);consthandle=awaitpreviewToDOM(doc,document.getElementById("preview")!);// later:handle.dispose();

@office-kit/docx-preview wraps the OSS docx-preview renderer behind a stable function-API entry point. The wrap is intentional and final — see docs/PLAN-PREVIEW.md for the rationale.

Scope

In scope

  • WordprocessingML (.docx) — read, edit, write.
  • OPC packaging (ECMA-376 Part 2), DrawingML — as the underlying layers.
  • Browser preview@office-kit/docx-preview wraps docx-preview so callers can render docx content into a DOM container without spinning up a server.

Out of scope (for now)

  • .pptx (PresentationML) and .xlsx (SpreadsheetML).

Out of scope (permanent)

  • Rendering to PDF, headless Word automation, binary .doc (pre-2007).

If a feature request only makes sense for pptx / xlsx, it will be redirected to a more appropriate library. See CLAUDE.md ("Scope discipline").

Repository layout

.
├── src/ # @office-kit/docx — the published library
│ ├── index.ts # public entry (re-exports src/api)
│ ├── api/ # public Docx wrapper (docx / validator / version)
│ └── internal/ # bundled layers — not separate npm packages
│ ├── opc/ # OPC (ZIP + Content Types + rels)
│ ├── xml/ # namespace-aware XML parser/serializer
│ └── wordprocessingml/ # WML AST + parsers + builders
├── packages/
│ └── preview/ # @office-kit/docx-preview — browser preview (wraps docx-preview)
├── site/ # SvelteKit docs site (pagefind search + preview playground)
├── docs/
│ ├── specs/ # Distilled spec notes + ECMA-376 fetcher target
│ └── PLAN-PREVIEW.md # Why @office-kit/docx-preview wraps docx-preview, final
├── references/ # External OSS / spec material (submodules)
├── scripts/
│ ├── fetch-specs.sh # Downloads ECMA-376 PDFs + XSDs into docs/specs/
│ ├── generate-samples.mjs # `pnpm sample` — writes 32 demonstration .docx files
│ └── check-tree-shake.mjs # `pnpm check:tree-shake` — bundle-budget CI gate
├── .changeset/ # Changesets — drives versioning + npm release
├── .github/ # Issue / PR templates and CI / release / deploy workflows
├── .claude/skills/ # Workflow guides for Claude Code agents
├── CLAUDE.md # Engineering principles for contributors and AI
├── CONTRIBUTING.md # Dev environment, workflow, code style
├── PLAN.md # Living implementation plan + progress table
├── SECURITY.md # Private vulnerability reporting
├── .oxlintrc.json # oxlint config
└── .oxfmtrc.json # oxfmt config (Prettier-compatible)

Development

pnpm install # one-time setup (use --recurse-submodules for fixture corpora)
pnpm -r run typecheck # tsc --noEmit (library + preview)
pnpm lint # oxlint
pnpm format:check # oxfmt --check
pnpm build # tsdown (rolldown) — builds the @office-kit/docx library
pnpm build:all # build every workspace package (library, preview, site)
pnpm test# vitest (source-resolved, no build step needed)
pnpm check:tree-shake # CI bundle-budget gate (~42 KB minimal vs ~131 KB full)
pnpm sample # writes demonstration .docx files into ./samples/

For the docs site:

pnpm --filter word-kit-site dev # http://localhost:5173 with hot reload
pnpm --filter word-kit-site build # static export + pagefind search index

See .claude/skills/run-check-and-test/SKILL.md for the canonical pre-PR quality gate.

Contributing

  • Read CONTRIBUTING.md for the development environment, workflow, and test layout.
  • Issues and PRs must follow the templates under .github/. Submissions that strip the template structure are auto-closed by the template-compliance workflow.
  • Read CLAUDE.md before opening a PR — it covers the "one way to do one thing" rule, defensive programming, comments, and the hard "no"s (no as unknown as T, no N+1, etc.).

License

MIT

About

A JavaScript library for Word (DOCX) files

Resources

Contributing

Security policy

Stars

2 stars

Watchers

1 watching

Forks

Releases

Packages

Contributors

Languages