How to decompress woff2 to ttf online
- Step 1Drop your WOFF2 file onto the zone — The drop-zone accepts a single font file (the label reads "Drop a TTF, OTF, WOFF, or WOFF2 file"). For this tool the decompressor checks the magic bytes after you run it: the first four must be `wOF2` (`0x774F4632`). A file named `.woff2` that is actually WOFF, TTF, or a TrueType Collection is rejected — see the [edge cases](#edge-cases-and-what-actually-happens).
- Step 2Confirm there are no options to set — WOFF2-to-TTF has zero configuration — no charset, no hinting toggle, no batch list. The options panel is empty by design because decompression is deterministic. If you need to strip or change anything (hinting, name records, glyphs) that is a separate step on the decompressed file.
- Step 3Run the decompression — Clicking run instantiates the `wawoff2` WebAssembly module and calls `decompress` on the bytes. It performs Brotli decompression plus glyf-table reconstruction to rebuild a flat sfnt. A typical 30–100 KB Latin WOFF2 expands in a few hundred milliseconds; large CJK fonts take longer.
- Step 4Check the reported flavour and size — The result panel shows `Decompressed format` (TTF or OTF) and `Inflated size` in KB. If it says OTF, the source wrapped CFF/PostScript outlines — that is expected, not corruption. Verify the inflated size is roughly 2.5–3.5× the WOFF2 input for Latin fonts.
- Step 5Download the auto-named output — The file is named from the source stem with the correct extension: `Inter-Regular.woff2` → `Inter-Regular.ttf`, or `.otf` if CFF-flavoured. The download is a real sfnt blob with the matching MIME (`font/ttf` or `font/otf`).
- Step 6Install or pass it downstream — Open the `.ttf`/`.otf` in your OS font manager, or feed it to a sibling tool: [font-metadata-extractor](/font-tools/font-metadata-extractor) for the name table, [hinting-stripper](/font-tools/hinting-stripper) to drop `fpgm`/`prep`/`cvt `, or [font-format-identifier](/font-tools/font-format-identifier) to re-confirm the magic. To go the other way, [ttf-to-woff2](/font-tools/ttf-to-woff2).
What the decompressor does, byte by byte
The full pipeline from dropped file to download. There are no user-tunable steps — every decision is driven by the file's own magic bytes.
| Stage | Behaviour | Outcome |
|---|---|---|
| Magic-byte gate | Reads the first 4 bytes; requires wOF2 (0x774F4632) | Anything else fails: Expected a WOFF2 file but detected <FORMAT> |
| Brotli + glyf decode | Instantiates the wawoff2 WASM module, calls decompress (Brotli + glyf-table reconstruction) | A flat in-memory sfnt buffer; on failure throws wawoff2 decompress failed |
| Flavour sniff | Reads the decompressed buffer's first 4 bytes | 0x00010000/true → TTF; OTTO → OTF |
| Extension + MIME | TTF → .ttf + font/ttf; OTF → .otf + font/otf | Output named <stem>.<ext> from the source filename |
| Metrics | Computes Decompressed format and Inflated size (KB) from the output length | Shown in the result panel before you download |
Magic bytes and what they mean for this tool
The four-byte signature decides whether the file decompresses, and into what. Only wOF2 is valid input here; the rest tell you which sibling tool to use instead.
| First 4 bytes | Format | What this tool does |
|---|---|---|
77 4F 46 32 (wOF2) | WOFF2 | Decompresses — this is the only accepted input |
77 4F 46 46 (wOFF) | WOFF 1.0 | Rejected — it is zlib-wrapped, not Brotli; nothing to do (WOFF is already close to TTF in workflow, but this tool will not touch it) |
00 01 00 00 | TTF (TrueType sfnt) | Rejected — it is already a TTF; no decompression needed |
4F 54 54 4F (OTTO) | OTF (CFF sfnt) | Rejected — already an installable OTF |
74 74 63 66 (ttcf) | TTC (TrueType Collection) | Rejected — multi-face container, not a WOFF2; use a TTC splitter |
74 72 75 65 (true) | TTF (Apple variant) | Rejected — already TrueType |
Tier file-size limits
The per-job upload ceiling by plan. Almost every real font is well under the free limit; the larger tiers exist for big CJK and icon fonts.
| Tier | Max file size | Typical headroom |
|---|---|---|
| Free | 5 MB | Any Latin/Cyrillic/Greek font; most CJK subsets |
| Pro | 50 MB | Full multi-script CJK fonts (compressed WOFF2 is usually 5–15 MB) |
| Developer | 1 GB | Effectively unlimited for fonts; paid tiers can auto-route to the local @jadapps/runner |
Cookbook
Concrete decompression scenarios with the exact result-panel output and downloaded filename. The tool has no options, so each recipe is really about reading the input correctly.
Plain TrueType WOFF2 → TTF
ExampleThe common case: a Latin web font (TrueType outlines) wrapped as WOFF2. The decompressor sees 0x00010000 after Brotli decode and writes a .ttf.
Input: Inter-Regular.woff2 (wOF2 magic, 34 KB) Run: wawoff2.decompress -> sfnt buffer Flavour sniff: 00 01 00 00 -> TrueType Result panel: Decompressed format: TTF Inflated size: 312.4 KB Download: Inter-Regular.ttf (font/ttf)
CFF-flavoured WOFF2 → OTF (not corrupt)
ExampleA PostScript/CFF font wrapped as WOFF2. The decompressed magic is OTTO, so the tool writes .otf and the metric reads OTF. This is correct — it is not a failed TTF conversion.
Input: SourceSerif-Regular.woff2 (wOF2 magic) Flavour sniff: 4F 54 54 4F (OTTO) -> CFF/PostScript Result panel: Decompressed format: OTF Inflated size: 198.7 KB Download: SourceSerif-Regular.otf (font/otf) Note: extension is .otf, NOT .ttf. The font has CFF outlines; that is the correct container.
Mislabelled .woff2 that is really WOFF 1.0
ExampleAn old build tool emitted a zlib WOFF and named it .woff2. The magic gate catches it before any decompression is attempted.
Input: legacy-font.woff2 (actually wOFF magic) Error shown: Expected a WOFF2 file but detected WOFF. Fix: run font-format-identifier to confirm the real format, then handle the WOFF directly.
Truncated download → Brotli failure
ExampleA WOFF2 that was cut short mid-transfer. The magic is intact (so the gate passes) but the Brotli stream is incomplete, so wawoff2 throws. WOFF2 has no error correction — one missing byte is fatal.
Input: Heading.woff2 (wOF2 magic, but truncated) Error shown: wawoff2 decompress failed (ConvertWOFF2ToTTF returned false). Fix: re-download from the source. Compare the byte length against the server's Content-Length.
Round-trip a Google Fonts WOFF2 for desktop use
ExampleDesigners often want the exact production weight installed locally to mock up comps. Decompress the CDN WOFF2, install the TTF, then verify the licence before redistributing.
1. Download the served file from fonts.gstatic.com (e.g. roboto-v30-latin-regular.woff2) 2. Drop it here -> Roboto-Regular.ttf 3. Install via Font Book / Settings -> Fonts 4. Check the licence string: feed the .ttf to font-metadata-extractor (Google Fonts ship SIL OFL; name IDs 13/14)
Edge cases and what actually happens
Every row below was probed against the live API. Some documented requirements (alphabetical axis order, numerical tuple order) are not actually enforced in practice — useful to know if you've been blaming the wrong thing for a 400.
Source WOFF2 wraps CFF — you get .otf, not .ttf
By designIf the decompressed magic is OTTO, the font has CFF/PostScript outlines and the tool writes .otf with font/otf. This is the correct container — renaming it to .ttf can confuse strict installers. The tool name says "to TTF" because TrueType is the common case, but it honours the actual outline format. Expect this for many Adobe and serif families.
File named .woff2 is actually WOFF, TTF, OTF, or a TTC
Expected — detected <FORMAT>The decompressor reads the magic before doing anything. A WOFF (wOFF), bare TTF (0x00010000), OTF (OTTO), or TrueType Collection (ttcf) mislabelled with a .woff2 extension fails with Expected a WOFF2 file but detected <FORMAT>. This is a guard, not a bug — run font-format-identifier to see what you actually have.
Brotli stream is corrupt or truncated
Decompression failedWOFF2 carries no error-correction. A single flipped or missing byte in the Brotli payload makes the whole file undecodable, and wawoff2 throws wawoff2 decompress failed (ConvertWOFF2ToTTF returned false). The usual cause is an incomplete download. Re-fetch from the source and compare byte lengths.
Decompressed sfnt has a different SHA-256 than the upstream TTF
Preserved (functionally identical)WOFF2 normalises table ordering and re-pads tables during the round-trip, so the byte-for-byte hash of the decompressed sfnt can differ from the original TTF the foundry shipped — while rendering, glyphs, kerning, and hinting are all identical. If you need the literal original bytes, keep the source TTF; if you need a working desktop font, the decompressed one is correct.
File exceeds your tier's size limit
Rejected — over limitThe per-job ceiling is 5 MB on free, 50 MB on Pro, 1 GB on Developer. A file above your limit is blocked before decompression with an upgrade prompt. Compressed WOFF2 is small, so this only bites on very large CJK fonts on the free tier — upgrade or use a subset.
You expected one font but the source was a collection
Rejected — detected TTCWOFF2 wraps exactly one face. If your file is a multi-face TrueType Collection it has the ttcf magic, not wOF2, and is rejected. There is no "extract face N" option here; split the TTC into single faces first, then (if needed) compress each to WOFF2 with ttf-to-woff2.
Hinting survives the round-trip
PreservedWOFF2 carries the fpgm, prep, and cvt tables intact, so a hinted source decompresses to a hinted TTF. If you want an unhinted TTF (smaller, fine for modern high-DPI rendering), run the output through hinting-stripper — this tool will not drop hinting on its own.
Name table, licence, and vendor ID all survive
PreservedWOFF2 does not strip metadata. Copyright (name ID 0), manufacturer (8), licence (13), licence URL (14), and the OS/2 vendor ID all round-trip exactly into the decompressed sfnt. That is why this tool is the first step in a licensing audit — see extract fonts for a licensing audit.
Buffer too short to identify
Rejected — unknown formatA file under four bytes (a stray empty or near-empty download) cannot be magic-sniffed and is reported as unknown rather than WOFF2, so decompression never starts. Re-download — the file is empty or a fragment.
Inflated size looks huge
ExpectedWOFF2 commonly compresses Latin fonts to 30–40% of the raw sfnt, so a 100 KB WOFF2 inflating to ~300 KB is normal — Brotli plus glyf preprocessing is doing its job. CJK fonts can inflate 2–4× as well. The Inflated size metric is informational; a large number is not corruption.
Frequently asked questions
Will I get an exact copy of the original font?
Functionally yes — every glyph, kerning pair, OpenType feature, and hinting table is reconstructed. But WOFF2 normalises table ordering and padding during the round-trip, so the decompressed sfnt's SHA-256 may differ from the upstream TTF the foundry shipped even though the rendering is byte-for-byte identical on screen. If you need the literal original bytes, keep the source; if you need a usable desktop font, the decompressed one is correct.
Why did my WOFF2 decompress to .otf instead of .ttf?
Because the wrapped outlines are CFF/PostScript, not TrueType. After Brotli decode the tool sniffs the magic: OTTO means CFF, so it writes .otf with font/otf. This is correct — do not rename it to .ttf, as strict installers key off the magic and would treat a CFF font labelled .ttf as malformed. Many serif and Adobe families are CFF-flavoured.
Can I install the result on my desktop?
Yes. Open the .ttf or .otf in Font Book (macOS), drag it onto Settings → Fonts (Windows), or run fc-cache (Linux). FontForge, Glyphs, and FontLab all accept it too. Always confirm the licence allows desktop use before installing or redistributing — feed the file to font-metadata-extractor to read name IDs 13 (licence) and 14 (licence URL).
Are there any options or settings?
No. WOFF2-to-TTF is a deterministic decompressor — there is no charset picker, no hinting toggle, no output-format choice, and no batch list. The options panel is intentionally empty. Every decision (TTF vs OTF extension) is made automatically from the decompressed magic bytes. If you need to change the font afterwards, use a dedicated sibling tool on the output.
What if the file fails to decompress?
Two likely causes. First, it is not actually a WOFF2 — the magic gate throws Expected a WOFF2 file but detected <FORMAT>; run font-format-identifier to confirm. Second, it is a genuine WOFF2 but the Brotli stream is corrupt or truncated (usually an incomplete download), which throws wawoff2 decompress failed. WOFF2 has no error correction, so re-fetch the file and compare its byte length to the server's.
Is the result hinted?
Yes, if the source was hinted. WOFF2 preserves the fpgm, prep, and cvt tables exactly, so a hinted web font decompresses to a hinted desktop font. If you want to drop hinting for a smaller file or because you are targeting only high-DPI rendering, run the decompressed TTF through hinting-stripper.
Does the decompressed font keep kerning and OpenType features?
Yes. kern, GSUB, and GPOS survive the round-trip untouched, so kerning pairs, ligatures, and stylistic sets all work in the decompressed font. WOFF2 is a lossless wrapper around the sfnt — it does not discard layout tables. To inspect what features are present, feed the output to opentype-features-inspector (it accepts the TTF/OTF you just produced).
Can it handle a TrueType Collection (TTC)?
No. WOFF2 wraps exactly one face, so a multi-face TTC has the ttcf magic, not wOF2, and is rejected as "detected TTC". There is no per-face extraction option here. Split the collection into single faces with a TTC splitter first; if you then need WOFF2 again, use ttf-to-woff2.
Is there a file-size limit?
Yes: 5 MB on the free tier, 50 MB on Pro, 1 GB on Developer. Because WOFF2 is already heavily compressed, even large multi-script CJK fonts usually land well under the Pro limit. The free tier comfortably handles any Latin, Cyrillic, or Greek font and most CJK subsets.
Does anything get uploaded to a server?
No. Decompression runs entirely in your browser via the wawoff2 WebAssembly module — the font bytes never leave your device. The only server-side write is an anonymous usage counter (run count, no file content) for signed-in dashboard stats. Paid tiers can optionally route the job to a local @jadapps/runner on your own machine, which is also fully local.
Why convert WOFF2 to TTF at all if they render the same?
Because the rendering is identical but the container is not. Desktop font managers, most PDF generators, native mobile font APIs, and font editors only accept raw sfnt (TTF/OTF) and reject the wOF2 magic. So you decompress when you need to install, inspect, audit, or feed the font to a tool that does not speak WOFF2. For the full trade-off, see WOFF2 vs TTF: when each format wins.
Can I batch-decompress a whole folder?
Not in the browser UI — it processes one file per run. For hundreds of files, script it: the Node wawoff2 package ships the same WASM module, or on a paid tier POST each file to the local runner. See automate WOFF2 to TTF extraction at scale for both approaches.
Privacy first
Every JAD Font tool runs entirely in your browser using opentype.js and the wawoff2 WASM Brotli encoder. Your fonts never leave your device — verified by zero outbound network requests during processing.