Read and write .docx files with Rust, WebAssembly, and JavaScript.
[dependencies]
docx-rs = "0.4"
pnpm add docx-wasm
The browser example below also uses file-saver.
pnpm add file-saver
Docx::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.
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 hello
The hello example writes output/examples/hello.docx.
Run the Rust test suite and lints from the workspace root:
make test
make lint
Review changed Rust snapshots with:
cargo insta review
Run the WebAssembly/JavaScript tests with:
corepack enable
cd docx-wasm
pnpm install --frozen-lockfile
pnpm test
Update Jest snapshots when an intentional output change requires it:
pnpm test -- --updateSnapshot
See CONTRIBUTING.md for the pull request workflow.
