ttf2woff2

Crates.iottf2woff2
lib.rsttf2woff2
version0.11.0
created_at2026-01-07 08:34:21.595384+00
updated_at2026-01-12 12:47:30.741281+00
descriptionA Pure Rust library and CLI for compressing TTF fonts to WOFF2 format.
homepagehttps://github.com/0x6b/ttf2woff2
repositoryhttps://github.com/0x6b/ttf2woff2
max_upload_size
id2027793
size97,539
kaoru (0x6b)

documentation

https://docs.rs/ttf2woff2

README

ttf2woff2

A Pure Rust library and CLI for compressing TTF fonts to WOFF2 format.

Features

  • Pure Rust - No C/C++ or Python dependencies
  • glyf/loca transformation - Achieves compression comparable to Google's woff2
  • 100% glyph fidelity - All glyph shapes are preserved exactly
  • Compatible with fonttools output

CLI Usage

$ cargo install ttf2woff2
$ ttf2woff2 --help
A Pure Rust library and CLI for compressing TTF fonts to WOFF2 format.

Usage: ttf2woff2 [OPTIONS] <INPUT>

Arguments:
  <INPUT>  Path to the input TTF file

Options:
  -o, --output <OUTPUT>    Path to the output WOFF2 file (defaults to input with .woff2 extension)
  -q, --quality <QUALITY>  Brotli compression quality (0-11) [default: 9]
  -h, --help               Print help
  -V, --version            Print version

Library Usage

Add to your Cargo.toml with default-features = false to exclude the CLI.

[dependencies]
ttf2woff2 = { version = "0.10", default-features = false }
use ttf2woff2::{encode, BrotliQuality};

let ttf_data = std::fs::read("font.ttf")?;
let woff2_data = encode(&ttf_data, BrotliQuality::default())?;
std::fs::write("font.woff2", &woff2_data)?;

Node.js / WASM Usage

A WASM build is available on npm as @0x6b/ttf2woff2-wasm:

$ npm install @0x6b/ttf2woff2-wasm
const ttf2woff2 = require("@0x6b/ttf2woff2-wasm");
const fs = require("fs");

const ttf = fs.readFileSync("font.ttf");
const woff2 = ttf2woff2(ttf);
fs.writeFileSync("font.woff2", woff2);

Performance

Benchmarks on NotoSansJP-Medium (17,808 glyphs, 5,729,332 bytes) on Apple M4 Pro:

$ hyperfine --warmup 3 --runs 5 \
  './target/release/ttf2woff2 tests/fixtures/NotoSansJP-Medium.ttf -o /tmp/noto-q11-ttf2woff2.woff2 -q 11' \
  './target/release/ttf2woff2 tests/fixtures/NotoSansJP-Medium.ttf -o /tmp/noto-q9-ttf2woff2.woff2 -q 9' \
  'uv run --with fonttools --with brotli python -c "from fontTools.ttLib import TTFont; f=TTFont(\"tests/fixtures/NotoSansJP-Medium.ttf\"); f.flavor=\"woff2\"; f.save(\"/tmp/noto-fonttools.woff2\")"'
Implementation Brotli Quality Time (s) Output Size (bytes)
Rust 11 3.10 2,322,432
Rust 9 0.33 2,424,432
Python fonttools 11 9.49 2,322,836

Validation

Tests generate WOFF2 files and validate against fonttools:

$ cargo test

Manual validation (need uv installed):

$ uv run scripts/validate.py <font.ttf> <font.woff2>

Regenerate pre-generated fonttools output for faster tests:

$ uv run scripts/generate_golden.py

License

Alternatives

If you need byte-for-byte compatibility with Google's woff2 converter, decompression support, or WOFF1 support, consider these alternatives:

  • woofwoof - Wraps Google's C++ woff2 library with pure Rust brotli. Supports both compression and decompression.
  • bodoni/woff - Wraps Google's C++ woff2 and C brotli. Supports WOFF1 and WOFF2.

Acknowledgments

This project started as an FFI wrapper around Google's woff2 and brotli C/C++ libraries, then evolved into a pure Rust implementation (v0.10.0) with assistance from AI coding assistants (Claude Code, Codex, and Amp). While the code has been tested and validated against fonttools, users should verify output for production use.

References

Commit count: 148

cargo fmt