How to Convert TTF to WOFF2 — Web Font Guide for Developers (2026)

TTF OTF WOFF2 @font-face Brotli Core Web Vitals
TTF → WOFF2 — key facts
~30% smallerthan WOFF
~50%+ smallerthan raw TTF
Brotlicompression
All modernbrowsers supported

WOFF2 is the web font format that belongs in production. It wraps the same glyph outlines as your TTF or OTF, but compresses them with Brotli, cutting bytes on the critical rendering path and improving how fast your text paints. This guide shows the quickest browser method, the real CLI commands developers actually use, the exact @font-face block to reference the file, and how the three formats compare on size and browser support.

1. Quick Answer

The direct answer: To convert TTF (or OTF) to WOFF2, the fastest no-install route is a browser tool like Convertlo's font converter — drop the file and it produces a real Brotli-compressed WOFF2 entirely in your browser via WebAssembly, nothing uploaded. On the command line, use Google's woff2_compress font.ttf, or with Python run pip install fonttools brotli then fonttools ttLib.woff2 compress -o font.woff2 font.ttf. In Node, ttf2woff2 streams a TTF in and a WOFF2 out. All produce the same WOFF2 that every modern browser supports.

2. Why WOFF2 Is the Format to Ship

WOFF and WOFF2 are not new outline formats — they are containers. A WOFF file wraps an existing sfnt font (TrueType/glyf or OpenType/CFF) plus compression. WOFF 1.0 used zlib/DEFLATE. WOFF2 replaced that with Brotli, plus a font-specific glyph and table transform, which is why it consistently beats WOFF by roughly 30% and an uncompressed TTF by 50% or more.

Those saved bytes matter because a web font sits on the critical path for rendering text. A smaller font file downloads sooner, the browser can swap in your typeface faster, and your Largest Contentful Paint — usually a heading or body text block — resolves earlier. On mobile connections the difference between a 120 KB TTF and a 45 KB WOFF2 is measurable in Core Web Vitals field data.

Browser support is no longer a reason to hesitate: WOFF2 is supported in every current version of Chrome, Edge, Firefox, and Safari, plus their mobile counterparts. The practical rule for 2026 is ship WOFF2 as the primary format and only add a WOFF or TTF fallback if your analytics still show a meaningful share of legacy browsers.

3. TTF vs WOFF vs WOFF2 — Size & Support

Exact bytes depend on the typeface, its glyph count, and hinting, but the relative ordering is consistent across virtually every font. Using a typical Latin text face as the baseline:

Format Compression Relative size Browser support Use as
TTF / OTF None (raw sfnt) 100% (baseline) Universal, but not web-optimized Source / last-resort fallback
WOFF zlib / DEFLATE ~60–70% of TTF All browsers incl. IE 9+ Legacy fallback
WOFF2 Brotli + transform ~40–50% of TTF All modern browsers Primary — ship this

In other words, WOFF2 is commonly cited at around 30% smaller than WOFF and roughly half the size of a raw TTF. If you only serve one format, serve WOFF2.

4. Method 1: Browser Converter (No Install)

When you just need a WOFF2 without touching a terminal — or you are on a locked-down machine — the fastest path is Convertlo's font converter. It converts TTF, OTF, WOFF, and WOFF2 between each other and produces a genuine Brotli-compressed WOFF2. The conversion runs 100% in the browser using WebAssembly, so the font file never leaves your device.

1
Open convertlo.pro/font-converter.html

Works in any modern browser on Windows, Mac, or Linux. No account, no upload, no install.

2
Drop your TTF or OTF file and choose WOFF2 as the output

Drag the font onto the converter or browse for it. Select WOFF2 as the target format. You can queue several files at once for a whole family.

3
Download the Brotli-compressed WOFF2

Conversion completes in a second or two locally. Download the .woff2 and drop it into your /fonts directory. Nothing was sent to a server.

Convert TTF/OTF to WOFF2 — free, in-browser, nothing uploaded

Real Brotli WOFF2 generated locally with WebAssembly. Works both directions between TTF, OTF, WOFF, and WOFF2.

5. Method 2: CLI — woff2_compress, fonttools, ttf2woff2

For build pipelines and repeatable automation, generate WOFF2 on the command line. Three well-established tools cover every environment.

Google's woff2_compress (reference encoder)

The woff2 project from Google is the reference implementation. After building it (or installing via your package manager, e.g. brew install woff2 or apt install woff2), it is a single command per file:

bash

# produces font.woff2 next to the input
woff2_compress font.ttf

# OTF works exactly the same
woff2_compress font.otf

There is also woff2_decompress font.woff2 to go back to sfnt, which is handy for verifying a round-trip.

fonttools (Python — most flexible)

If you already have Python, fonttools with the Brotli backend is the most script-friendly option and integrates with subsetting in the same toolchain:

bash

pip install fonttools brotli

# compress TTF or OTF to WOFF2
fonttools ttLib.woff2 compress -o font.woff2 font.ttf

# decompress back to sfnt to verify
fonttools ttLib.woff2 decompress -o font.ttf font.woff2

ttf2woff2 (Node)

For JavaScript/Node build steps, ttf2woff2 reads a TTF on stdin and writes WOFF2 on stdout, so it drops into any pipe or npm script:

bash

npm install -g ttf2woff2

# stream a TTF in, get WOFF2 out
ttf2woff2 < font.ttf > font.woff2

Tip: All three encoders are lossless — they repackage and Brotli-compress the existing outlines and tables. The WOFF2 you get from the browser tool, woff2_compress, fonttools, and ttf2woff2 are byte-comparable in size and identical in what browsers render. Pick whichever fits your workflow.

6. The @font-face Snippet

Once the .woff2 is in place, reference it with an @font-face rule. List WOFF2 first so modern browsers download only that; add a WOFF (or TTF) fallback if you still support legacy browsers. Always set font-display: swap so text stays visible while the font loads:

css

@font-face {
  font-family: 'MyFont';
  src: url('/fonts/myfont.woff2') format('woff2'),
       url('/fonts/myfont.woff')  format('woff');
  font-weight: 400;
  font-style: normal;
  font-display: swap;
}

body {
  font-family: 'MyFont', system-ui, sans-serif;
}

The browser walks the src list in order and uses the first format it supports, so a modern browser never downloads the WOFF fallback. For faster start-of-render, also preload the primary file in your <head>:

html

<link rel="preload" href="/fonts/myfont.woff2" as="font"
      type="font/woff2" crossorigin>

The crossorigin attribute is required on font preloads even for same-origin fonts — omit it and the browser fetches the font twice, wasting the preload. Match the preloaded file to the one your primary @font-face actually serves.

7. Going Further: Subsetting

Converting to WOFF2 shrinks the file, but the biggest wins often come from subsetting — stripping glyphs you never use. A full Latin + Cyrillic + Greek font carries thousands of glyphs; an English-only site may use a few hundred. Subset first, then compress to WOFF2, and the file can drop dramatically further.

bash

# pyftsubset (ships with fonttools) — subset AND output WOFF2 in one step
pyftsubset font.ttf \
  --unicodes=U+0000-00FF \
  --flavor=woff2 \
  --output-file=font.subset.woff2

glyphhanger is a companion tool that crawls your live pages and reports exactly which Unicode code points you actually render, then hands that set to pyftsubset automatically — so you subset to precisely what your site uses rather than guessing a range.

Subsetting is the one step that is lossy by design: removed glyphs are gone. Keep the original TTF/OTF in source control, and be careful with dynamic or user-generated text (names, other languages) that may need code points outside your subset.

8. Frequently Asked Questions

How do I convert TTF to WOFF2?
The fastest no-install method is a browser-based converter like Convertlo's font converter: drop the TTF file, and it produces a real Brotli-compressed WOFF2 locally using WebAssembly, with nothing uploaded. On the command line, use Google's woff2_compress font.ttf, or with Python run pip install fonttools brotli then fonttools ttLib.woff2 compress -o font.woff2 font.ttf. In Node, ttf2woff2 reads a TTF on stdin and writes WOFF2 on stdout. All of these output the same WOFF2 format that every modern browser supports.
Why use WOFF2 instead of TTF or WOFF for the web?
WOFF2 uses Brotli compression, which makes it roughly 30% smaller than WOFF and often 50% or more smaller than an uncompressed TTF. Smaller font files mean less bytes on the critical path, faster text rendering, and a better Largest Contentful Paint score. WOFF2 is supported by every modern browser (Chrome, Edge, Firefox, Safari, and mobile equivalents), so for production sites it is the primary format to ship. TTF and WOFF are only needed as fallbacks for very old browsers.
Can I convert OTF to WOFF2 the same way?
Yes. WOFF2 is a container that can wrap either TrueType (glyf) or PostScript/CFF (OTF) outlines, so every tool that converts TTF to WOFF2 also converts OTF to WOFF2. Convertlo's font converter accepts OTF directly, woff2_compress font.otf works, and fonttools ttLib.woff2 compress -o font.woff2 font.otf handles CFF outlines. The resulting WOFF2 keeps the original outline type; no rasterization or quality loss occurs.
Is WOFF2 conversion lossless?
Yes. Converting TTF or OTF to WOFF2 only repackages and compresses the existing glyph outlines and font tables with Brotli; it does not rasterize glyphs or discard hinting or metrics. Decompressing a WOFF2 reproduces the original sfnt font. The only way you lose data is if you deliberately subset the font to remove unused glyphs, which is a separate optional optimization step.
How do I reference a WOFF2 file in CSS?
Use an @font-face rule that lists WOFF2 first with format('woff2'), optionally followed by a WOFF or TTF fallback, and add font-display: swap so text is visible while the font loads. For example: @font-face { font-family: 'MyFont'; src: url('/fonts/myfont.woff2') format('woff2'), url('/fonts/myfont.woff') format('woff'); font-weight: 400; font-style: normal; font-display: swap; }. Browsers pick the first format they support, so modern browsers download only the WOFF2.

Generate WOFF2 in your browser — free and private

Convert TTF or OTF to a real Brotli-compressed WOFF2 with no install and no upload, then drop it straight into your @font-face rule.

Ship WOFF2 as your primary web font, keep a WOFF/TTF fallback only if your traffic needs it, subset when you can, and preload the file that matters. That combination gives you the smallest possible font payload and the fastest text render.

Convertlo Editorial Team
We build and maintain the browser-based file tools on Convertlo. These guides come from the team that engineers the software itself — every method here uses a tool we wrote and run entirely in your browser, with nothing uploaded to a server.
More articles