§ 01 · Getting started
Install, build a document, write the bytes.
word-kit is a function-first WordprocessingML library. Every operation is a standalone
export that takes a Docx value as its first argument; nothing is hidden behind
a class instance. That keeps the public surface tree-shakeable and makes the library work
the same way in Node and in browsers.
Install
$ pnpm add @office-kit/docx @office-kit/docx-preview @office-kit/docx is the authoring API. @office-kit/docx-preview is an
optional companion that mounts a read-only preview of any Docx value into a DOM
container. Both ship as ESM with bundled .d.ts types and have no Node-only
dependencies.
Build a document from scratch
The "hello world" of word-kit. Every helper here lives on @office-kit/docx; createDocx hands back a plain Docx object that the rest of the API treats as a value.
// Build a .docx from scratch. This file is imported as ?raw into the
// docs site so the snippet shown to readers is exactly what svelte-check
// type-checked — if an API rename breaks it, the docs build fails.
import {
addBulletList,
addTable,
appendHeading,
appendParagraph,
createDocx,
PAGE_SIZE_A4,
setPageSize,
toUint8Array,
} from "@office-kit/docx";
const doc = createDocx({ paragraphs: [] });
setPageSize(doc, PAGE_SIZE_A4);
appendHeading(doc, "Quarterly review", 1);
appendParagraph(doc, "Highlights from Q3.");
addBulletList(doc, ["Shipped preview", "Round-trip stable", "512 tests green"]);
addTable(doc, [
["Metric", "Q2", "Q3"],
["MRR", "$120k", "$148k"],
["Churn", "3.1%", "2.4%"],
]);
const bytes: Uint8Array = toUint8Array(doc);
void bytes;
Open a template, fill placeholders
Existing .docx files can be opened with openDocx and edited
in place. word-kit preserves every XML element it does not yet model as a pass-through
node, so re-saving an unmodified template doesn't trip Word's "needs repair" prompt.
replaceTextEverywhere walks every story — body, headers, footers, footnotes,
endnotes, comments, textboxes — not just the main document. Run-spanning matches like {{name}} split across multiple runs are joined before the regex sees them.
// Open an existing .docx as a template, run cross-part placeholder
// substitution, write it back. The interesting bit: replaceTextEverywhere
// also walks headers / footers / footnotes / textboxes — not just the
// body — so {{name}} in a header swaps out too.
import { openDocx, replaceTextEverywhere, toUint8Array } from "@office-kit/docx";
declare const templateBytes: Uint8Array;
declare const values: Record<string, string>;
const doc = openDocx(templateBytes);
const replaced: number = replaceTextEverywhere(
doc,
/\{\{(\w+)\}\}/g,
(m) => values[m.captures[0] ?? ""] ?? "",
);
const out: Uint8Array = toUint8Array(doc);
void replaced;
void out;
Render in the browser
The companion package @office-kit/docx-preview mounts a read-only preview of any Docx (or raw bytes) into a DOM container. It wraps the OSS docx-preview renderer behind a stable function-API entry point.
You can play with it on the playground, or read the recipes for embedding patterns.
What's next
- Recipes — common scenarios, copy-paste ready
- API reference — every public export, grouped by area
- Playground — drop a .docx and see preview
- GitHub — source + issues