Packers
Packers are the way in which
docxturns your code into.docxformat. It is completely decoupled from thedocx.Document.
Packers work in browsers, workers, Node.js, Bun, and Deno. A packer can return portable Uint8Array bytes, a Blob, a string, a base64 string, an ArrayBuffer, or a web ReadableStream. It is up to you to persist or transfer that output. This library does not export PDF.
Export as portable bytes
toUint8Array works consistently in every supported runtime. Node's file APIs accept a Uint8Array directly.
Packer.toUint8Array(doc).then((bytes) => {
fs.writeFileSync("My Document.docx", bytes);
});toBuffer remains as a deprecated alias for compatibility and also returns a Uint8Array.
Export as string
Packer.toString(doc).then((string) => {
console.log(string);
});Export as a base64 string
Packer.toBase64String(doc).then((string) => {
console.log(string);
});Export as Blob
This is useful if you want to send it as an downloadable in a browser environment.
Packer.toBlob(doc).then((blob) => {
// saveAs from FileSaver will download the file
saveAs(blob, "example.docx");
});Export as ArrayBuffer
This may be useful when working in a Node.js worker.
Packer.toArrayBuffer(doc).then((arrayBuffer) => {
port.postMessage(arrayBuffer, [arrayBuffer]);
});Export as a Stream
toReadableStream returns a web-standard ReadableStream, which works in the browser and in Node.js.
const stream = Packer.toReadableStream(doc);
// In the browser, e.g. as a Response body
const response = new Response(stream);
// In Node.js, pipe to a file
import { Writable } from "node:stream";
import * as fs from "node:fs";
await stream.pipeTo(Writable.toWeb(fs.createWriteStream("example.docx")));Export using optional arguments
The Packer methods support 2 optional arguments.
The first is for controlling the indentation of the xml and should be a boolean or one of the PrettifyType values:
| PrettifyType | Indentation string |
|---|---|
NONE | "" |
WITH_2_BLANKS | " " (2 spaces) |
WITH_4_BLANKS | " " (4 spaces) |
WITH_TAB | "\t" (tab) |
Passing prettify: true is equivalent to PrettifyType.WITH_2_BLANKS (two spaces); false (or omitting the argument) leaves the xml unindented.
import { Packer, PrettifyType } from "betterdocx";
Packer.toString(doc, PrettifyType.WITH_4_BLANKS).then((string) => {
console.log(string);
});The second is an array of subfile overrides ({path: string, data: string}[]). These overrides can be used to write additional subfiles to the result or even override default subfiles in the case that the default handling of these subfiles does not meet your needs.
const overrides = [{ path: "word/commentsExtended.xml", data: "string_data" }];
Packer.toString(doc, true, overrides).then((string) => {
console.log(string);
});Export to arbitrary formats
You can also use the lower-level Packer.pack method to export to any specified output type. It supports the full OutputType set:
base64, string, binarystring, array, uint8array, arraybuffer, blob
The return type follows the requested output type — for example, "uint8array" resolves to a Uint8Array:
const bytes = await Packer.pack(doc, "uint8array");
await fs.promises.writeFile("My Document.docx", bytes);Packer.pack also accepts the same optional prettify and overrides arguments as the convenience methods:
Packer.pack(doc, "string", PrettifyType.WITH_TAB).then((string) => {
console.log(string);
});