bokuweb/docx-rs

📝 A .docx file writer with Rust/WebAssembly.

Rust

558

842 commits

updated Oct 5, 2026

See the code

README

docx-rs

Read and write .docx files with Rust, WebAssembly, and JavaScript.


GitHub Actions Status docx-rs at crates.io docx-rs documentation docx-wasm at npm docx-wasm downloads

Installation

Rust

[dependencies]
docx-rs = "0.4"

Browser/Node.js

pnpm add docx-wasm

The browser example below also uses file-saver.

pnpm add file-saver

Usage

Write a document with Rust

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 a document with Rust

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),
)?;

Write a document in the browser

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

Write a document with Node.js

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

Read a document with JavaScript

const { readFileSync } = require("fs");
const { readDocx } = require("docx-wasm");

const document = readDocx(readFileSync("./hello.docx"));
console.log(document);

Supported capabilities

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.

Development

Requirements

Run a Rust example

Run examples from the workspace root:

cargo run -p docx-rs --example hello

The hello example writes output/examples/hello.docx.

Testing

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.

License

MIT

bokuweb/docx-rs

📝 A .docx file writer with Rust/WebAssembly.

Rust

558

842 commits

updated Oct 5, 2026

See the code

README

docx-rs

Read and write .docx files with Rust, WebAssembly, and JavaScript.


GitHub Actions Status docx-rs at crates.io docx-rs documentation docx-wasm at npm docx-wasm downloads

Installation

Rust

[dependencies]
docx-rs = "0.4"

Browser/Node.js

pnpm add docx-wasm

The browser example below also uses file-saver.

pnpm add file-saver

Usage

Write a document with Rust

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 a document with Rust

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),
)?;

Write a document in the browser

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

Write a document with Node.js

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

Read a document with JavaScript

const { readFileSync } = require("fs");
const { readDocx } = require("docx-wasm");

const document = readDocx(readFileSync("./hello.docx"));
console.log(document);

Supported capabilities

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.

Development

Requirements

Run a Rust example

Run examples from the workspace root:

cargo run -p docx-rs --example hello

The hello example writes output/examples/hello.docx.

Testing

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.

License

MIT

Project health

Overall

5.9/10

Maintained

10/10

Code review

3/10
OpenSSF Scorecard

crates.io

Latest release

0.4.22 · Jul 21, 2026

Releases this year

4

Significant stargazers

Edgar Ramírez Mondragón

195 followers · starred Feb 2026

Robin

341 followers · starred Apr 2026

Michaël Benesty

448 followers · starred Nov 2025

yhirano55

443 followers · starred Jan 2023