Skip to content

office-kit/docx

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

120 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

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 scratch
const doc = createDocx({ paragraphs: ["Hello, world."] });
appendParagraph(doc, "Bullets:");
addBulletList(doc, ["one", "two", "three"]);
addTable(doc, [
  ["Name", "Score"],
  ["Alice", "90"],
]);
setPageSize(doc, PAGE_SIZE_A4);
const bytes = toUint8Array(doc);

// From an existing .docx template
const tpl = openDocx(existingDocxBytes);
replaceTextEverywhere(tpl, /\{\{(\w+)\}\}/g, (m) => values[m.captures[0]!] ?? "");
const out = 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";

const doc = openDocx(bytes);
const handle = await previewToDOM(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

License

Contributing

Security policy

Stars

0 stars

Watchers

1 watching

Forks

Packages

 
 
 

Contributors