Read and write .docx files with Rust, WebAssembly, and JavaScript.
[dependencies]
docx-rs = "0.4"pnpm add docx-wasmThe browser example below also uses file-saver.
pnpm add file-saverDocx::pack writes the package directly to the output file. Use
Docx::build().pack(...) only when you need access to the rendered XML package
before it is archived.
use docx_rs::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let file = std::fs::File::create("./hello.docx")?;
Docx::new()
.add_paragraph(Paragraph::new().add_run(Run::new().add_text("Hello")))
.pack(file)?;
Ok(())
}read_docx parses a DOCX package into the same Docx model used by the writer.
The model can also be serialized to JSON. Packages whose ASCII ZIP part names
conflict with their resolved filenames are rejected.
use docx_rs::*;
fn main() -> Result<(), Box<dyn std::error::Error>> {
let bytes = std::fs::read("./hello.docx")?;
let docx = read_docx(&bytes)?;
println!("{}", docx.json());
Ok(())
}Image previews are generated by default. If you only need the original embedded image bytes, disable preview generation to avoid decoding and re-encoding them:
let docx = read_docx_with_options(
&bytes,
ReadDocxOptions::default().with_image_previews(false),
)?;import { saveAs } from "file-saver";
import("docx-wasm").then((w) => {
const buffer = new w.Docx()
.addParagraph(
new w.Paragraph().addRun(new w.Run().addText("Hello world!"))
)
.build();
saveAs(new Blob([buffer]), "hello.docx");
});const w = require("docx-wasm");
const { writeFileSync } = require("fs");
const buffer = new w.Docx()
.addParagraph(new w.Paragraph().addRun(new w.Run().addText("Hello world!")))
.build();
writeFileSync("hello.docx", Buffer.from(buffer));const { readFileSync } = require("fs");
const { readDocx } = require("docx-wasm");
const document = readDocx(readFileSync("./hello.docx"));
console.log(document);The Rust API supports both document generation and parsing, including:
- Paragraphs, runs, text formatting, borders, tabs, and breaks
- Tables, nested tables, numbering, styles, and theme colors
- Inline and floating images
- Headers, footers, page settings, and sections
- Hyperlinks, bookmarks, comments, footnotes, and tracked changes
- Tables of contents, structured data tags, custom properties, and custom XML
The WebAssembly package exposes document generation and DOCX-to-JSON parsing for browser and Node.js applications. OOXML is a large specification, so support is not exhaustive.
See the Rust API documentation and examples directory for the full API and focused examples.
- Rust 1.88 (see
rust-toolchain) - Node.js and Corepack
- pnpm 9.6.0
- wasm-pack 0.13.1
- cargo-insta for reviewing Rust snapshots
Run examples from the workspace root:
cargo run -p docx-rs --example helloThe hello example writes output/examples/hello.docx.
Run the Rust test suite and lints from the workspace root:
make test
make lintReview changed Rust snapshots with:
cargo insta reviewRun the WebAssembly/JavaScript tests with:
corepack enable
cd docx-wasm
pnpm install --frozen-lockfile
pnpm testUpdate Jest snapshots when an intentional output change requires it:
pnpm test -- --updateSnapshotSee CONTRIBUTING.md for the pull request workflow.
