better docx
Exporting

Packers

Packers are the way in which docx turns your code into .docx format. It is completely decoupled from the docx.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:

PrettifyTypeIndentation 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);
});

On this page