How to woff2 vs ttf: which format to use when
- Step 1Identify the delivery medium — Where is the font consumed? Browser page, desktop install, PDF render, native mobile bundle, or HTML email. The medium — not the font — decides the format. This is the only question that matters.
- Step 2Apply the rule — Browser-fetched and rendered by a browser engine → WOFF2 (smallest, universally supported since 2018). Everything else → raw sfnt: TTF for TrueType outlines, OTF for CFF. Email gets a system-font fallback because Outlook strips `@font-face` entirely.
- Step 3Keep one canonical source — Hold the font as TTF/OTF in your design system or repo. It is the lossless master both directions derive from: compress to WOFF2 for the web, ship the raw sfnt to desktop/PDF/mobile pipelines.
- Step 4Convert per medium in the browser — Need web bytes from a TTF master? Use [ttf-to-woff2](/font-tools/ttf-to-woff2). Inherited only a WOFF2 and need the desktop/PDF sfnt back? Use this tool to decompress to TTF/OTF. Both run client-side.
- Step 5Confirm the bytes are what you think — Before shipping, run [font-format-identifier](/font-tools/font-format-identifier) on each artifact. A `.ttf` that is really CFF (`OTTO` magic) or a `.woff2` that is really WOFF causes silent renderer or installer quirks.
- Step 6Write the policy down — Pin the per-medium decision in your design-system docs in one paragraph. A documented rule prevents the recurring "why is the production font 800 KB / why won't Font Book open this?" investigations.
Format by delivery medium
The decision matrix. The medium dictates the format; the font is identical either way. Convert in whichever direction the row needs.
| Medium | Use | Why | Convert with |
|---|---|---|---|
| Web page (browser) | WOFF2 | Smallest wire format; supported by every browser since 2018 | ttf-to-woff2 from your TTF master |
| Desktop install (Font Book, Windows Fonts) | TTF / OTF | Font managers do not decompress WOFF2 — they read raw sfnt only | This tool (WOFF2 → TTF/OTF) |
| PDF generation | TTF / OTF | Most PDF libraries embed sfnt fonts and reject the wOF2 container | This tool, then embed the sfnt |
| Native mobile bundle (iOS/Android) | TTF / OTF | Native font APIs load sfnt; WOFF2 is a web-only format | This tool to recover the sfnt |
| Font editor (FontForge, Glyphs) | TTF / OTF | Editors open sfnt; pre-WOFF2 tools never added Brotli decode | This tool to get an editable sfnt |
| HTML email | System-font fallback (WOFF2 only where supported) | Outlook desktop strips every @font-face; design for the fallback | n/a — rely on a robust system stack |
TTF and WOFF2 head to head
Same sfnt, two wrappers. Everything that matters for rendering is identical; only delivery characteristics differ.
| Property | TTF | WOFF2 |
|---|---|---|
| Magic bytes | 0x00010000 (or true) | wOF2 (0x774F4632) |
| Compression | None (raw sfnt) | Brotli + glyf-table preprocessing |
| Typical wire size (Latin) | Baseline (e.g. ~300 KB) | ~30–40% of TTF (e.g. ~100 KB) |
| Browser support | Works, but wasteful | Universal since 2018 |
| Desktop installable | Yes | No (managers reject it) |
| PDF / native mobile | Yes | No |
| Glyphs / kerning / hinting / features | All present | All present (identical) |
| Rendering | Reference | Pixel-identical to TTF |
Cookbook
Concrete per-medium decisions with the conversion direction spelled out. The same font binary backs every row.
Shipping a brand font to the web
ExampleYou have the foundry TTF. Web visitors should never download the raw sfnt — compress to WOFF2 and serve that.
Source: BrandSans-Regular.ttf (312 KB)
-> ttf-to-woff2 -> BrandSans-Regular.woff2 (~104 KB)
@font-face {
font-family: "Brand Sans";
src: url(/fonts/BrandSans-Regular.woff2) format("woff2");
font-display: swap;
}
Result: ~67% smaller payload, identical rendering.Installing a production web font on your desktop
ExampleYou only have the served WOFF2 and want to mock up comps in a desktop app. Decompress back to TTF/OTF and install it.
Source: served Inter-Regular.woff2 -> woff2-to-ttf -> Inter-Regular.ttf Install: open in Font Book / Settings -> Fonts. (Check the licence first via font-metadata-extractor.)
Embedding a web font in a generated PDF
ExampleMost PDF toolchains (pdf-lib, reportlab, wkhtmltopdf) embed sfnt and reject WOFF2. Recover the TTF first.
Source: HeadingFont.woff2 (web asset) -> woff2-to-ttf -> HeadingFont.ttf Then embed HeadingFont.ttf in the PDF pipeline. WOFF2 handed directly to the embedder = 'unsupported font format' error.
Bundling a font in a native mobile app
ExampleiOS and Android font APIs load sfnt. A WOFF2 in the bundle silently fails to register.
Source: AppIcons.woff2 -> woff2-to-ttf -> AppIcons.ttf (or .otf if CFF) Drop the .ttf into the app's font assets and register it. WOFF2 is web-only; native APIs ignore it.
Email: design for the fallback, not the font
ExampleOutlook desktop renders email through Word's HTML engine and strips every @font-face. No format choice fixes this — build a strong system stack.
/* Apple Mail, iOS, Gmail render WOFF2; Outlook does not */ font-family: "Brand Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; /* The email must still read like itself in the system font when @font-face is stripped. */
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.
Desktop font managers reject WOFF2
By designFont Book, Windows Fonts, FontForge, and Glyphs read raw sfnt and never added WOFF2 (Brotli) decompression — the format is too web-specific to justify it. Hand them a .woff2 and they error or ignore it. Decompress to TTF/OTF with this tool first; that is the entire reason WOFF2-to-TTF exists.
Most PDF libraries cannot embed WOFF2
Unsupported formatPDF embeds fonts as sfnt programs. Libraries like pdf-lib, reportlab, and wkhtmltopdf expect TTF/OTF and reject or fail to embed a WOFF2 container. Recover the sfnt with this tool before embedding. The rendered PDF is then identical to the web font.
Native mobile font APIs ignore WOFF2
Web-only formatiOS and Android font-registration APIs load sfnt. A WOFF2 bundled in app assets registers as nothing — no error, just a missing font. Convert to TTF/OTF for the bundle. This is a delivery-medium mismatch, not a corruption issue.
CFF-flavoured font converts to .otf, not .ttf
ExpectedIf the source has CFF/PostScript outlines, decompressing its WOFF2 yields an OTTO-magic file the tool names .otf. That is the correct container for desktop install and PDF — do not force it to .ttf. The 'TTF' in tool names refers to the common TrueType case.
Shipping raw TTF to the web 'because it works'
Wasteful — avoidBrowsers do render TTF, so it appears to work — but you are shipping 2.5–3.5× the bytes for zero visual benefit. On a multi-weight family this is hundreds of KB of avoidable, render-affecting payload. Compress to WOFF2 with ttf-to-woff2.
WOFF 1.0 as a fallback in 2026
Rarely neededWOFF2 has universal support across every browser in active development. A WOFF 1.0 fallback only matters for genuinely ancient or Brotli-less embedded WebViews — check analytics before adding one, since every fallback you list costs extra bytes. WOFF, like WOFF2, is desktop-unfriendly.
Outlook desktop strips @font-face regardless of format
Browser-engine specificOutlook on Windows renders through Microsoft Word's HTML engine, which removes every @font-face rule — inline or linked, WOFF2 or TTF. No format choice fixes it. Design the email so the system-font fallback still looks like the brand; Apple Mail, iOS, and Gmail do render WOFF2.
Rendering differs between TTF and WOFF2
Cannot happenIt does not — the decompressed WOFF2 contains the byte-equivalent sfnt tables, so outlines, hinting, kerning, and layout features are identical. If two builds render differently, the fonts are genuinely different files (different versions or subsets), not the same font in two wrappers.
Hash mismatch after a TTF → WOFF2 → TTF round-trip
Preserved (functionally)WOFF2 normalises table ordering and padding, so a TTF → WOFF2 → TTF round-trip can produce a different SHA-256 than the original TTF while rendering identically. Keep your TTF master if you need bit-stability; the round-tripped file is a valid, equivalent font for all rendering purposes.
Same family, but one weight only exists as WOFF2
RecoverableIf a teammate committed only the WOFF2 of a weight and the TTF master is lost, you can still recover a usable sfnt by decompressing — the result is functionally complete (all glyphs, kerning, hinting). Promote that decompressed TTF/OTF to your master and re-derive the web WOFF2 from it going forward.
Frequently asked questions
Why don't desktops accept WOFF2?
Desktop font managers (Font Book, Windows Fonts, FontForge, Glyphs) read raw sfnt and never added WOFF2's Brotli decompression — it is a web-specific format with no desktop benefit. So for any desktop install you need TTF or OTF. Decompress with this tool, then open the result in your font manager.
Is the rendering identical between TTF and WOFF2?
Yes, pixel-for-pixel. The decompressed WOFF2 contains the byte-equivalent sfnt tables, so outlines, hinting, kerning, ligatures, and OpenType features are unchanged. WOFF2 changes only the wire format, never the font. If two builds look different, they are different files — not the same font in two wrappers.
How much smaller is WOFF2 than TTF?
For a typical Latin font, WOFF2 is about 30–40% of the raw TTF size — a 60–70% saving — thanks to Brotli plus glyf-table preprocessing. The exact ratio depends on glyph count and outline complexity, but the saving is large enough that shipping TTF to the web is almost always wasteful. Decompressing back to TTF inflates by the inverse factor (2.5–3.5×).
When should I use TTF over WOFF2?
Whenever the consumer is not a browser: desktop install, PDF generation, native mobile bundles, and font editors all need raw sfnt and reject WOFF2. Use WOFF2 only for fonts fetched over HTTP and rendered by a browser engine. The medium decides — the font is identical either way.
Which direction do I convert?
From a TTF master to the web: compress with ttf-to-woff2. From an inherited WOFF2 back to a desktop/PDF/mobile sfnt: decompress with this tool. Keep one canonical TTF/OTF master in your repo and derive both directions from it so you never lose the lossless source.
What about WOFF (1.0) for desktop?
Same answer as WOFF2 — desktop apps do not decompress it either. WOFF and WOFF2 are both web formats; TTF and OTF are the everything-else formats. In 2026, WOFF2 has universal browser support, so a WOFF 1.0 fallback is rarely worth its extra bytes.
Will WOFF2 ever replace TTF on desktop?
Unlikely. Desktops have no bandwidth pressure, and decompressing a font every time the OS loads it would burn CPU for no benefit. TTF/OTF remain the desktop standard, which is exactly why a WOFF2-to-TTF decompressor is a recurring need rather than a legacy curiosity.
Can I serve TTF and WOFF2 from the same @font-face?
You can list both in src with format() hints, and the browser picks the first it supports — but since every modern browser supports WOFF2, the TTF entry is dead weight that only inflates your CSS. List WOFF2 alone unless analytics prove you need a fallback for an ancient client.
Does converting WOFF2 to TTF lose anything?
No data is lost — every glyph, kerning pair, hinting instruction, and OpenType feature survives. The only difference is that table ordering and padding are normalised, so the SHA-256 may differ from the original TTF. Rendering is identical. Keep the original master if you need bit-stable bytes.
Why is my production hero font 800 KB?
Almost certainly because someone shipped the raw TTF (or even a WOFF) to the web instead of WOFF2. Convert it with ttf-to-woff2 — a single-weight Latin font usually drops well under 150 KB. If the font is also unsubset, subsetting it first (font-subsetter) cuts it further.
How do I confirm which format a file really is?
Check the magic bytes. WOFF2 is wOF2, WOFF is wOFF, TTF is 0x00010000, OTF is OTTO. The fastest way is font-format-identifier, which reads just the first four bytes locally. Mislabelled extensions are common and cause both renderer and installer quirks.
Where can I read the deeper format internals?
See WOFF & WOFF2 spec internals explained for the container layout and why WOFF2 beats WOFF, and WOFF2 decompression edge cases for the failure modes when a file is corrupt or mislabelled.
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.