npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@office-kit/docx

v0.1.1

Published

OOXML-compliant .docx generation for browser and Node.js.

Readme

@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