GALAXY OF TOOLS

TYPE SECTOR

Font Subsetter – Shrink Web Fonts to the Characters You Use

Keep only the characters you need, drop hinting, pin variable axes and get a tiny WOFF2 with its unicode-range.

Drop a TTF, OTF, WOFF, WOFF2, TTC or EOT font here or click to choose · nothing is uploaded

Subsetting runs in your browser with HarfBuzz compiled to WebAssembly; the font never leaves your device. Check the font's licence allows subsetting and web embedding — the OFL does, many commercial licences do not.

Runs entirely in your browser. Nothing you enter or upload is sent to a server.

Free for everyone. If this tool saved you time, buy me a coffee.

Font subsetter: ship only the glyphs your pages use

A full font family can weigh 200–600 KB per style, and a Devanagari or CJK font several megabytes, yet a landing page might use eighty characters. This font subsetter keeps only the characters you choose — typed text, Unicode blocks, or CSS-style ranges — drops hinting and glyph names, optionally pins the axes of a variable font to a single weight, and writes a tiny WOFF2 together with the @font-face rule and unicode-range that match it. A 500 KB TTF often becomes a 15–25 KB web font.

The subsetting is done by HarfBuzz, the shaping engine browsers and Android use, compiled to WebAssembly. It keeps every glyph the kept characters can turn into (Indic conjuncts, Arabic joining forms, fi ligatures, kerning pairs) instead of deleting glyphs by code point. The companion font converter changes formats and outlines; this page changes what is inside.

Everything happens in your browser, so unreleased fonts never leave your device. Check the licence: the SIL Open Font License allows subsetting; many commercial web-font licences do not.

How to use the Font Subsetter

  1. Drop a TTF, OTF, WOFF, WOFF2, TTC or EOT file on the box, or press Try a sample font.
  2. Choose the characters to keep: paste text into Text or characters, tick Unicode blocks such as Basic Latin, Devanagari or Arabic, and add Extra Unicode ranges in CSS syntax (U+0900-097F, U+20B9). The counter shows how many code points are selected and how many the font lacks.
  3. Tick Keep every glyph instead to only remove hinting, drop layout features or make a static instance.
  4. Set the Output format, which OpenType layout features to keep, and whether to remove hinting and keep glyph names. For a variable font, leave each axis variable or pin it to a value.
  5. Press Subset font. The result shows the size change, counts before and after, requested characters the font lacks, a live preview and the @font-face rule with the exact unicode-range.
  6. Press Download, put the file next to your CSS and paste the rule.

Font Subsetter features

HarfBuzz closure

Glyphs reachable through GSUB (ligatures, Indic and Arabic shaping) and GPOS (kerning, marks) are kept automatically, so subset text shapes exactly like the full font.

Variable-font instancing

Pin wght, wdth or any axis to one value and HarfBuzz bakes a static instance; or keep the axes and subset the variation data too.

Honest missing-character report

Requested characters the font does not have are listed with code points, so you add a fallback face instead of finding tofu in production.

unicode-range done right

The rule lists the exact code points left in the subset, collapsed into ranges, so browsers skip the download when a page does not use them.

Script presets, India first

Devanagari, Bengali, Gurmukhi, Gujarati, Odia, Tamil, Telugu, Kannada and Malayalam presets include ₹, zero-width joiners and the dotted circle Indic text needs, plus Latin, Cyrillic, Greek, Arabic, Hebrew, Thai, kana, Hangul, CJK and emoji.

Controls over size

Remove hinting (a large share of a hand-hinted TrueType file), drop glyph names, pick WOFF2, WOFF or a plain TTF/OTF; licence and copyright records are always kept.

What makes a web font big — and what you can safely remove

Part of the fontTypical shareSafe to drop for the web?
Glyph outlines you never use (other scripts, small caps, old-style figures)The largest partYes — that is what character subsetting removes.
TrueType hinting (fpgm, prep, cvt, glyph instructions)Large in hand-hinted fonts, near zero in many Google Fonts buildsUsually; macOS, iOS, Android and modern Windows ignore or override it.
Layout tables (GSUB, GPOS)Small to mediumKeep them: dropping them breaks ligatures, kerning and Indic or Arabic shaping; subsetting trims them anyway.
Variation data (gvar, HVAR, …)Large in variable fontsKeep if you use several weights; pin the axis if you use one.
Glyph names (post table)A few KBYes for the web; keep them for desktop or editing use.

Worked example (measured with this engine)

Noto Sans Regular as served by Google Fonts is a 543 KB TTF with 4,688 glyphs covering Latin, Greek, Cyrillic and Devanagari. Subset with the Devanagari preset plus Basic Latin, punctuation and digits, it becomes a 55 KB WOFF2 (1,278 glyphs); Basic Latin with Latin-1 and punctuation gives 19 KB; Basic Latin alone 12 KB; the whole font as WOFF2 without subsetting is 165 KB. Give the Hindi and English files the same font-family with their own unicode-range and an English page never downloads the Devanagari glyphs. Afterwards, inline a tiny subset with the Base64 encoder or minify the stylesheet with the CSS minifier.

  • Keep all layout features for Indic, Arabic, Thai and Khmer fonts; "Latin basics" is only for Latin, Greek and Cyrillic.
  • Add the Currency symbols block or type ₹ € £ $ — prices are the characters people most often forget. The sample font lacks ₹, which the counter flags.
  • Pinning the sample variable font (300–700) to one weight shrinks its WOFF2 from 21 KB to 12.5 KB; make one file per weight you use.

Font Subsetter FAQ

Is it safe to subset a font?

Technically yes: the result is a standard font with the glyphs and layout rules the kept characters need. Legally it depends on the licence: SIL OFL, Apache 2.0 and Ubuntu Font Licence fonts may be subset and embedded; many commercial licences forbid modification, and some set the OS/2 "no subsetting" bit.

How much smaller will my font get?

Keeping Basic Latin plus punctuation from a multi-script font usually leaves a few percent of the original: the 543 KB Noto Sans above becomes 19 KB of WOFF2. Keeping a whole script such as CJK leaves far more.

Why does the preview show boxes for some characters?

Those characters are not in the subset: either you did not select them or the original font lacks them (the missing-character note lists these). Add a fallback font family in your CSS so the browser substitutes another face.

Can I subset a variable font and keep it variable?

Yes. Leave each axis on "Keep variable" and the subset carries the variation tables for the kept glyphs; the @font-face rule then uses the axis range, for example font-weight: 300 700.

Does the subsetter keep kerning and ligatures?

Yes, with "Keep all" layout features (the default). Pairs and ligatures between kept characters stay; those involving removed glyphs are pruned.

What should I do with the unicode-range?

Paste the whole rule into your CSS. The browser downloads the file only when a page uses a character in that range, so one family can be split into per-script files under one font-family name.

You might also need