Web Open Font Format 2
WOFF2 wraps TTF/OTF font data in a Brotli-compressed container with glyph-specific preprocessing, producing files 30% smaller than WOFF and 50–60% smaller than raw TTF. Google Fonts serves WOFF2 by default since 2016. FileDex provides reference information only.
WOFF2 font conversion requires glyph-level processing unavailable in browser environments. FileDex displays format information and CLI conversion commands.
Common questions
What is a WOFF2 file?
WOFF2 is a compressed web font format that wraps TrueType or OpenType font data using Brotli compression and font-specific byte transforms. Standardized by the W3C in 2018, it produces files 30% smaller than WOFF and 50–60% smaller than raw TTF, making it the preferred format for web font delivery across all modern browsers.
Should I use WOFF2 or TTF for my website?
WOFF2 for all web font delivery. It is 50–60% smaller than TTF with identical rendering quality, and every modern browser supports it (97%+ global coverage). Keep the source TTF for desktop font installation and font editing workflows. A WOFF-only fallback is unnecessary unless you support IE 9–11.
Can I install a WOFF2 font on my computer?
Desktop operating systems cannot install WOFF2 directly — it must be decompressed back to TTF or OTF first. Font editor applications like FontForge perform this conversion losslessly. Once decompressed, install the resulting font through Font Book on macOS or right-click → Install on Windows. See the CLI tab below for command-line options.
How much smaller is WOFF2 compared to WOFF?
WOFF2 files are approximately 30% smaller than equivalent WOFF files. The improvement comes from Brotli compression replacing zlib, plus font-specific preprocessing that splits glyph data into optimized sub-streams before compression. A 94 KB WOFF font typically becomes about 66 KB as WOFF2.
Do I still need a WOFF fallback with WOFF2?
Only if you need to support Internet Explorer 9–11, which Microsoft retired in June 2022. All actively maintained browsers — Chrome 36+, Firefox 39+, Safari 10+, Edge 14+ — have supported WOFF2 natively since at least 2016. Google Fonts stopped serving WOFF as a fallback in 2020. Most production sites now serve WOFF2-only with no compatibility issues.
What is the difference between WOFF and WOFF2?
WOFF uses zlib compression on individual font tables. WOFF2 uses Brotli compression on all tables as a single stream, plus font-specific preprocessing that splits glyph outlines into separate data streams. The result is 30% smaller files. Both are W3C standards with similar browser support.
Does WOFF2 support variable fonts?
Yes. WOFF2 wraps the complete OpenType specification, including variable font tables (fvar, gvar, STAT). A single variable WOFF2 file can replace four to eight static weight files while being smaller than two of them, making variable fonts plus WOFF2 the most efficient web typography approach.
How do I subset a WOFF2 font?
Font subsetting removes unused glyphs from a WOFF2 file, keeping only the character ranges your site actually uses — Latin, Arabic, Cyrillic, or specific Unicode blocks. This can shrink a full-range font from 120 KB to 15–25 KB for Latin-only content. Font editing applications and build tools handle subsetting; see the CLI tab below for the exact command.
What makes .WOFF2 special
What is WOFF2?
WOFF2 (Web Open Font Format 2.0) is a W3C font packaging standard that compresses TrueType and OpenType font data using Brotli and font-specific byte transforms. A 100 KB TTF file typically becomes 40–50 KB as WOFF2. The format was published as a W3C Recommendation on 1 March 2018, edited by Vladimir Levantovsky, with Google providing the open-source reference encoder and decoder.
Continue reading — full technical deep dive
Compression pipeline
WOFF2 does not simply Brotli-compress raw font tables. Before compression, a preprocessing stage derived from Monotype’s MicroType Express technology restructures the data:
glyf table transform. The glyph outline table—typically the largest table in a TrueType font—is split into seven independent sub-streams: nContour values, nPoints values, flags, coordinates (x/y deltas), composite glyph data, bounding boxes, and hinting instructions. Splitting these streams groups similar data types together, which Brotli can then compress far more efficiently than interleaved glyph records.
loca table elimination. The loca (glyph location) table, which stores byte offsets into glyf, is not included in the compressed stream at all. Decoders reconstruct it by walking the decompressed glyf data and recording the start offset of each glyph.
Single-stream Brotli compression. Unlike WOFF 1.0, which compresses each font table independently with zlib, WOFF2 concatenates all (transformed) tables into one buffer and compresses them as a single Brotli stream. This allows the compressor to find cross-table redundancies—repeated byte sequences in head, hhea, OS/2, and name tables, for example—that per-table compression misses.
The combined effect is files approximately 30% smaller than WOFF 1.0 (which itself is 40–50% smaller than raw TTF). For a typical Latin font family shipping four weights, the WOFF2 total might be 150 KB versus 220 KB for WOFF or 380 KB for raw TTF.
Binary structure
Every WOFF2 file starts with a 48-byte header. The first four bytes are the ASCII signature wOF2 (hex 77 4F 46 32), distinguishing it from WOFF 1.0’s wOFF. The header also records the original sfnt flavor (00 01 00 00 for TrueType outlines, 4F 54 54 4F for CFF), the total file length, the number of tables, the decompressed sfnt size, the compressed data block size, version numbers, and optional offsets to metadata and private data blocks.
After the header comes the Table Directory. Each entry uses a flags byte that encodes the table tag (63 known tags have single-byte codes; unknown tags use a 4-byte literal), followed by UIntBase128-encoded original and transform lengths. UIntBase128 is a variable-length integer encoding where each byte contributes 7 data bits and the high bit signals continuation—similar to protocol buffers’ varint.
The compressed data block follows the directory. Optional metadata (Brotli-compressed XML carrying license and vendor information) and a private data block (opaque vendor data) may appear at the end of the file at offsets specified in the header.
Browser support timeline
WOFF2 adoption moved quickly once Google shipped it:
- Chrome 36 (July 2014) — first browser with WOFF2 support
- Opera 23 (2014) — Chromium-based, followed Chrome
- Firefox 39 (June 2015)
- Safari 10 (September 2016) — partial; full support in Safari 12.1
- Edge 14 (August 2016)
As of 2026, Can I Use reports over 97% global browser coverage. The only notable gap is IE 11, which Microsoft retired in June 2022.
Google Fonts and the WOFF2 default
Google Fonts—the largest free web font library—switched its default serving format from WOFF to WOFF2 around 2016. The service maintains over 30 optimized variants per font family and uses the User-Agent string to serve the best format for each browser. For modern browsers, that means WOFF2 with unicode-range subsetting: the CSS response includes multiple @font-face blocks, each covering a unicode range (Latin, Latin Extended, Cyrillic, etc.), so the browser downloads only the subsets it needs for the page’s actual text content.
Variable fonts and WOFF2
OpenType 1.8 (2016) introduced variable fonts, which encode an entire design space (weight, width, slant, optical size, custom axes) in a single file. Combined with WOFF2 compression, one variable font file can replace four to eight static weight files while being smaller than two of them. A static 4-weight Latin font family might total 160 KB as WOFF2; the equivalent variable font is often under 90 KB as WOFF2.
WOFF2 handles variable fonts without any special treatment—the gvar, fvar, STAT, and other variation tables are simply additional tables in the font that get included in the compressed stream.
Font subsetting
Full Unicode fonts can be 200–500 KB even as WOFF2. Subsetting removes unused glyphs before compression. For a Latin-only English site, subsetting a full-range font can reduce the WOFF2 from 120 KB to 15–25 KB. Tools like pyftsubset (from the fonttools Python library) and glyphhanger (Node.js, crawls a site to discover which characters are actually used) support direct WOFF2 output.
Google Fonts automates this: the CSS API’s unicode-range descriptors cause the browser to request only the glyph subsets needed for each page.
TrueType Collections in WOFF2
WOFF2 supports TrueType Collection (TTC) packaging via a Collection Directory that follows the Table Directory. Multiple fonts share common tables (cmap, name, OS/2) while maintaining separate glyph data. This is particularly efficient for CJK font families where shared ideograph tables can be deduplicated, saving megabytes across a family.
Performance implications
Fonts are render-blocking resources. The browser cannot paint text in a custom font until the WOFF2 file has been downloaded and decompressed. Smaller WOFF2 files directly reduce Time to First Render and improve Core Web Vitals metrics, particularly Largest Contentful Paint (LCP). Preloading critical WOFF2 files via <link rel="preload" as="font" type="font/woff2" crossorigin> eliminates the discovery delay that occurs when the browser must first download CSS before it encounters the @font-face declaration.
Standardization history
Google proposed WOFF2 in 2012, building on Brotli, which was initially developed specifically for font compression. The W3C published WOFF2 as a Candidate Recommendation in 2014. Brotli itself was formalized as RFC 7932 in July 2016. WOFF2 reached full W3C Recommendation status on 1 March 2018. The latest editorial revision of the specification is dated 08 August 2024. In 2021, the National Academy of Television Arts & Sciences awarded a Technology & Engineering Emmy to the W3C’s font technology standardization work, which includes WOFF2.
.WOFF2 compared to alternatives
| Formats | Criteria | Winner |
|---|---|---|
| .WOFF2 vs .WOFF | Compression algorithm WOFF2 uses Brotli (RFC 7932) with font-specific glyf/loca preprocessing. WOFF 1.0 uses zlib (DEFLATE) with per-table compression. Brotli’s single-stream approach finds cross-table redundancies that zlib misses. | WOFF2 wins |
| .WOFF2 vs .WOFF | File size WOFF2 files are approximately 30% smaller than equivalent WOFF files. A 94 KB WOFF font typically compresses to 66 KB as WOFF2, per web.dev benchmarks. | WOFF2 wins |
| .WOFF2 vs .TTF | Web delivery size WOFF2 achieves 50–60% smaller files than uncompressed TTF. A 652-byte TTF compressed to 300 bytes as WOFF2 in local testing (54% reduction). Real-world fonts show similar ratios. | WOFF2 wins |
| .WOFF2 vs .TTF | Desktop OS support Windows, macOS, and Linux install TTF fonts natively. WOFF2 cannot be installed as a system font—it must be decompressed to TTF/OTF first using woff2_decompress or fonttools. | TTF wins |
| .WOFF2 vs .OTF | Outline format support WOFF2 wraps both TrueType (quadratic B-splines) and CFF (cubic Bezier) outlines. The flavor field in the header indicates which: 00 01 00 00 for TrueType, 4F 54 54 4F for CFF. | Draw |
| .WOFF2 vs .EOT | Relevance (2026) EOT (Embedded OpenType) was Microsoft’s proprietary web font format for IE 6–8. IE usage dropped below 0.3% after Microsoft retired IE 11 in June 2022. WOFF2 has 97%+ global coverage. | WOFF2 wins |
| .WOFF2 vs .WOFF | Browser support Both cover 97%+ of browsers. WOFF additionally supports IE 9–11 (retired June 2022). For actively supported browsers in 2026, both have universal coverage. WOFF adds only dead-browser reach. | Draw |
Technical reference
- MIME Type
font/woff2- Magic Bytes
77 4F 46 32wOF2 signature.- Developer
- World Wide Web Consortium (W3C)
- Year Introduced
- 2014
- Open Standard
- Yes — View specification
wOF2 signature.
Binary Structure
A WOFF2 file begins with a 48-byte header: 4-byte signature (77 4F 46 32 = 'wOF2'), 4-byte flavor (the sfnt version of the original font—00 01 00 00 for TrueType, 4F 54 54 4F for CFF), 4-byte total file length, 2-byte numTables, 2-byte reserved (must be zero), 4-byte totalSfntSize (decompressed font data size), 4-byte totalCompressedSize, 2-byte majorVersion, 2-byte minorVersion, 4-byte metaOffset, 4-byte metaLength, 4-byte metaOrigLength, 4-byte privOffset, and 4-byte privLength. Following the header is the Table Directory: each entry contains a flags byte (encodes table tag using 63 known single-byte codes or a 4-byte literal for custom tags), plus UIntBase128-encoded origLength and transformLength fields. UIntBase128 is a variable-length encoding where each byte’s high bit signals continuation and the lower 7 bits carry data—up to 5 bytes for values up to 2^32-1. The glyf and loca tables undergo mandatory transforms: glyf is split into seven sub-streams (nContour, nPoints, flags, coordinates, composites, bounding boxes, instructions) and loca is reconstructed during decompression rather than stored. After the directory comes a single Brotli-compressed data block containing all font tables concatenated. For TrueType Collections, a Collection Directory follows the Table Directory, mapping each sub-font to shared and unique table indices. Optional Brotli-compressed XML metadata and a vendor-private data block may appear at the end.
| Offset | Length | Field | Example | Description |
|---|---|---|---|---|
0x00 | 4 bytes | Signature | 77 4F 46 32 (wOF2) | WOFF2 file identifier. Must be ASCII 'wOF2' (0x774F4632). Distinguishes from WOFF 1.0's 'wOFF'. |
0x04 | 4 bytes | Flavor | 00 01 00 00 (TrueType) | sfnt version of the original uncompressed font. 00 01 00 00 = TrueType outlines. 4F 54 54 4F = CFF outlines (OpenType/PostScript). |
0x08 | 4 bytes | Length | 00 00 01 2C (300 bytes) | Total size of the WOFF2 file in bytes. Browsers compare this against HTTP Content-Length for integrity. |
0x0C | 2 bytes | numTables | 00 0A (10) | Number of font tables in the table directory. Does not count loca, which is reconstructed. |
0x0E | 2 bytes | Reserved | 00 00 | Must be zero. Non-zero values indicate a malformed file. |
0x10 | 4 bytes | totalSfntSize | 00 00 02 8C (652 bytes) | Total size of the decompressed sfnt data. Used to pre-allocate memory buffers during decompression. |
0x14 | 4 bytes | totalCompressedSize | 00 00 00 E3 (227 bytes) | Size of the Brotli-compressed data block containing all concatenated font tables. |
0x18 | 2 bytes | majorVersion | 00 01 | Major version of the WOFF2 file. Current specification defines version 1. |
0x1A | 2 bytes | minorVersion | 00 00 | Minor version, typically 0. |
0x1C | 4 bytes | metaOffset | 00 00 00 00 | Byte offset to Brotli-compressed XML metadata block. Zero if no metadata present. |
0x20 | 4 bytes | metaLength | 00 00 00 00 | Compressed length of the metadata block in bytes. |
0x24 | 4 bytes | metaOrigLength | 00 00 00 00 | Uncompressed length of the metadata XML. Zero if no metadata. |
0x28 | 4 bytes | privOffset | 00 00 00 00 | Byte offset to private data block. Used by foundries for DRM or licensing data. |
0x2C | 4 bytes | privLength | 00 00 00 00 | Length of the private data block in bytes. |
Attack Vectors
- Brotli decompressor memory corruption
- Decompression bomb
- Font fingerprinting via unique subsets
Mitigation: FileDex does not decompress or rasterize WOFF2 files. All format analysis is reference-only. Browsers sandbox font decompression in dedicated processes (Chrome Site Isolation, Firefox RDD). WOFF2 parsing occurs after CORS validation, preventing cross-origin font data exfiltration.
- Specification WOFF File Format 2.0 — W3C Recommendation
- Specification Brotli Compressed Data Format — RFC 7932 (IETF)
- Registry font/woff2 MIME Type Registration — IANA
- History Web Open Font Format — Wikipedia
- Industry W3C Press Release: WOFF 2.0 Improves Compression (1 March 2018)
- Documentation Reduce Web Font Size — web.dev