| Crates.io | ttf2woff2 |
| lib.rs | ttf2woff2 |
| version | 0.11.0 |
| created_at | 2026-01-07 08:34:21.595384+00 |
| updated_at | 2026-01-12 12:47:30.741281+00 |
| description | A Pure Rust library and CLI for compressing TTF fonts to WOFF2 format. |
| homepage | https://github.com/0x6b/ttf2woff2 |
| repository | https://github.com/0x6b/ttf2woff2 |
| max_upload_size | |
| id | 2027793 |
| size | 97,539 |
A Pure Rust library and CLI for compressing TTF fonts to WOFF2 format.
$ 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
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)?;
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);
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 |
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
If you need byte-for-byte compatibility with Google's woff2 converter, decompression support, or WOFF1 support, consider these alternatives:
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.