How to adopt name table cleanup as a design-system policy
- Step 1Audit current waste across representative weights — Run [font-metadata-extractor](/font-tools/font-metadata-extractor) on three representative fonts to count name records, then run [name-table-cleaner](/font-tools/name-table-cleaner) and note Records before/dropped. Multiply the average drop by the number of weights to size the win.
- Step 2Confirm the licence allows it — Critical step: the cleaner removes nameID 0 (Copyright) and 7 (Trademark). Many foundry EULAs require the copyright string to stay embedded. Check each font's licence before adopting the policy for it. Licence description (13) and URL (14) are kept, but copyright is not.
- Step 3Write the policy precisely — Document the exact rule: 'All web fonts have their name table reduced to Windows-Unicode-English (platform 3, encoding 1, lang 0x409) records for nameIDs 1, 2, 4, 5, 6, 13, 14. Copyright (0), trademark (7), localised, and Mac-platform records are removed. Variable fonts are exempt unless axis names are not surfaced.'
- Step 4Decide the compression stage — Because the cleaner outputs uncompressed TTF, the policy must specify compression as a separate, final step via [ttf-to-woff2](/font-tools/ttf-to-woff2). Document the order: clean -> (strip hints) -> (subset) -> WOFF2.
- Step 5Enforce in CI — Add the clean + compress chain to the font build (or a prebuild hook). Gate merges so any new font weight goes through the same pipeline. Assert nameID 1 and 4 survive in the output as a build check.
- Step 6Report the saving — Track the per-weight drop and the final WOFF2 size build-over-build. Report cumulative bytes-saved-per-page-load — the number that justifies the policy to stakeholders and proves it's still working.
The policy: keep vs remove
The exact, fixed behaviour the policy commits to. There are no options — adopting the tool means adopting this keep-list verbatim.
| Record / nameID | Policy outcome | Why it's safe (or the caveat) |
|---|---|---|
| Family (1), Subfamily (2), Full name (4) | Kept | The records browsers match for @font-face — must stay |
| Version (5), PostScript name (6) | Kept | Useful for cache-busting and PDF/print embedding |
| Licence description (13), Licence URL (14) | Kept | Compliance-relevant; deliberately retained |
| Copyright (0), Trademark (7) | Removed | Caveat: some EULAs require copyright to stay — check before adopting per font |
| Mac-platform records (platformID 1) | Removed | Legacy; macOS reads Windows records since 2009 |
| Localised records (lang != 0x409) | Removed | Browsers read 0x409 regardless of user locale |
| Variable-font axis names (256+) | Removed | Caveat: breaks axis labels in design tools — exempt editable variable fonts |
Where name cleanup fits among font-optimisation steps
Name-table cleanup is one of several stacking optimisations. Each is a separate JAD tool; this is the recommended order.
| Step | Tool | Output |
|---|---|---|
| 1. Clean name table | name-table-cleaner | Uncompressed TTF, slim name table |
| 2. Strip hinting (optional) | hinting-stripper | TTF without instruction tables |
| 3. Subset to used glyphs (optional) | font-subsetter | TTF with reduced glyph set |
| 4. Compress (last) | ttf-to-woff2 | Web-ready WOFF2 |
Cookbook
Policy artefacts you can paste into a design-system handbook, plus the audit math that justifies the rule. The licence caveat is the part most teams forget — keep it in the policy text.
The policy statement (paste into docs)
ExampleA precise, honest policy that matches the tool's real behaviour, including the copyright caveat.
FONT METADATA POLICY - All web fonts: name table reduced to Windows-Unicode-English (platform 3, encoding 1, language 0x409) for nameIDs 1, 2, 4, 5, 6, 13, 14. - Removed: copyright (0), trademark (7), Mac-platform records, all non-English locales, variable-font axis names (256+). - Output is TTF; compress to WOFF2 as the final build step. - EXCEPTION: fonts whose EULA requires an embedded copyright string are exempt (or cleaned with a licence-preserving port). - EXCEPTION: variable fonts surfaced with named instances in design tools are exempt.
Sizing the win
ExampleAudit math from three representative weights. Multiply the average record drop by the number of weights and pages.
Audit (3 sample weights): Weight A: 68 records -> 7 (dropped 61, ~9 KB) Weight B: 52 records -> 7 (dropped 45, ~6 KB) Weight C: 18 records -> 7 (dropped 11, ~2 KB) Avg name-table drop ~5.7 KB (pre-compression) System: 9 weights -> ~51 KB removed before WOFF2. After WOFF2 the realised saving is smaller but still compounds with subsetting and hint-stripping.
CI gate that enforces the policy
ExampleReject a merge if a font in the build isn't in the canonical name shape. Pseudocode mirroring the keep-list.
for font in changed_fonts:
names = read_name_records(font)
canonical = all(r.platform==3 and r.encoding==1
and r.lang==0x409
and r.nameID in {1,2,4,5,6,13,14}
for r in names)
if not canonical:
fail(f"{font}: run name-table-cleaner before commit")Licence-compliance pre-check
ExampleBefore applying the policy to a font, verify its EULA tolerates copyright removal. Keep a manifest of exempt fonts.
# fonts/_metadata-policy.yml standard: # cleaned per policy (copyright removed) - Inter - IBM Plex Sans exempt_keep_copyright: # EULA requires nameID 0 - SomeFoundry Display # see licence sec 4.2 # -> clean with a fontTools port that also keeps nameID 0
Before/after a single weight
ExampleWhat a contributor sees in the tool's result panel after running a weight through cleanup.
Brand-Bold.woff2 -> name-table-cleaner Records before: 64 Records kept: 7 Records dropped: 57 Output: Brand-Bold.cleaned.ttf -> then ttf-to-woff2 -> Brand-Bold.cleaned.woff2
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.
Policy removes copyright the EULA requires
Licence riskThe single biggest policy mistake: the cleaner removes nameID 0 (Copyright) and 7 (Trademark), and several foundry EULAs require the copyright notice to remain embedded in the binary. Before adopting the policy for a licensed font, read its EULA. For exempt fonts, either skip the clean step or use a fontTools port that keeps nameID 0. Make this an explicit exception list in the policy, not an afterthought.
Variable fonts lose axis labels
Removed by designVariable-font axis and instance names (nameID 256+) are dropped. The axes still function, but a design tool reading the labels shows blanks, which degrades the editing experience for any consumer who opens the font. Exempt variable fonts that are meant to be surfaced with named instances, or clean only the static instances you ship.
Output is TTF, so an un-compressed font ships by mistake
Process gapThe cleaner outputs uncompressed TTF. A policy that stops at 'clean the name table' and forgets the compression stage will ship a larger file than the original WOFF2. Always document compression (ttf-to-woff2) as the final, mandatory step, and gate CI on the output being WOFF2 — not TTF.
Non-web pipelines need the full name records
Out of scopeThe policy is for web delivery. Fonts also used in PDF generation, native mobile app bundles, or print workflows sometimes rely on the broader name records (copyright for legal pages, localised names for regional apps, typographic family 16/17 for grouping). Scope the policy to the web build artifacts only; keep the source fonts intact for other pipelines.
Treating cleanup as an SEO lever
No direct effectSearch engines don't read font metadata, so name-table cleanup has zero direct SEO impact. The only indirect link is via payload: smaller fonts can help Core Web Vitals (LCP), which is a ranking input. Frame the policy as performance hygiene, not SEO — and don't overstate the bandwidth savings, which are modest per font (single-digit KB).
A font with no Windows-English record blocks the build
Error (intended)If a contributor adds a font that carries only Mac-platform or non-English records, the clean step errors with No Windows English name records to keep. That's the policy working — it refuses to ship a nameless font. The fix is to add a (3, 1, 0x409) record to the source, not to bypass the step.
Multi-weight superfamily relies on typographic family (16/17)
Removed by designLarge superfamilies (e.g. 8+ weights) sometimes use nameIDs 16/17 (Typographic family/subfamily) so applications group all weights under one menu entry. The cleaner drops 16/17. For pure browser delivery this is fine (browsers use 1/2), but if the same files feed a desktop app where weight grouping matters, exempt them or restore 16/17 in a port.
Overstating the annual bandwidth saving
Reporting accuracyBe conservative in stakeholder reports. The realised per-page saving is the post-WOFF2 delta, not the raw name-table bytes removed — WOFF2 already compresses redundant strings well, so the wire saving is a fraction of the pre-compression drop. Report measured WOFF2 size deltas, not theoretical pre-compression numbers, to keep the policy credible.
Frequently asked questions
Is name-table cleanup safe to mandate across the whole system?
For web delivery, yes — with two documented exceptions. First, fonts whose EULA requires an embedded copyright string (nameID 0), which the cleaner removes. Second, variable fonts surfaced with named instances in design tools, whose axis labels (nameID 256+) the cleaner drops. Outside those, reducing to the Windows-English keep-list has zero rendering or installation impact.
Does cleanup remove the copyright notice?
Yes. nameID 0 (Copyright) and 7 (Trademark) are not in the keep-list and are removed. The licence description (13) and URL (14) are kept. This is the most important thing to put in your policy: confirm each font's licence permits copyright removal, and maintain an exemption list for those that don't.
Which records does the policy keep, exactly?
Seven, all Windows-Unicode-English (platform 3, encoding 1, language 0x409): nameID 1 (Family), 2 (Subfamily), 4 (Full name), 5 (Version), 6 (PostScript name), 13 (Licence description), 14 (Licence URL). Everything else — Mac records, other languages, copyright, trademark, typographic family/subfamily, axis names — is removed. The list is fixed; there are no per-font options.
Why does the policy need a separate compression step?
Because the cleaner outputs uncompressed TTF regardless of input. If your policy stops at cleaning, you'd ship a larger file than the original WOFF2. The mandated order is: clean the name table, optionally strip hints and subset, then compress to WOFF2 last with ttf-to-woff2. Gate CI on the final artifact being WOFF2.
How big is the actual saving per font?
The pre-compression name-table drop is typically 1–3 KB for lightly-localised fonts and 5–15 KB for heavily-localised commercial ones. After WOFF2 compression the realised wire saving is smaller, because WOFF2 already compresses repeated strings. Report measured post-WOFF2 deltas to stakeholders, not the raw pre-compression numbers, to stay credible.
Does this help SEO?
Not directly — search engines don't parse font metadata. The only indirect path is performance: smaller fonts can improve LCP, a Core Web Vitals ranking input. Position the policy as performance and metadata hygiene, not as an SEO tactic. The bandwidth savings are real but modest per font.
What happens if someone adds a font that can't be cleaned?
If the font has only Mac-platform or non-English records, the clean step errors with No Windows English name records to keep and the build fails. That's the policy enforcing itself — it refuses to emit a nameless font. The contributor adds a (3, 1, 0x409) record to the source and re-runs, rather than bypassing the step.
Should the source fonts be cleaned too, or only build artifacts?
Only the web build artifacts. Keep the original/source fonts intact in version control, because the same files may feed PDF, native-app, or print pipelines that rely on the broader name records (copyright, localised names, typographic family). Run the clean step as part of the web build, producing cleaned WOFF2 in the public assets directory.
How do I enforce the policy without manual review?
Add the clean + compress chain to the font build and a CI gate that asserts each shipped font is in the canonical name shape (only the 7 keep-list records under 3/1/0x409) and is WOFF2, not TTF. Reject merges that introduce a font outside that shape. See the CI automation guide for runnable recipes.
Can the policy keep one extra language for a regional brand?
Not with the JAD tool — its keep-list is fixed to English-US. If your brand genuinely needs a localised name string preserved (for a regional desktop app, say), use a fontTools port that adds the extra language to the filter. For the web specifically you never need it: browsers read 0x409 regardless of locale.
How do I prove the policy is still working over time?
Track two numbers per build: the per-weight Records-dropped figure (from the tool's result panel or your port's logs) and the final WOFF2 size. Trend the total shipped font bytes per page build-over-build. Spot-check with font-metadata-extractor that identity records survived and copyright is gone where expected.
Does cleanup change which weight a browser picks?
No. Weight/style matching uses nameID 1/2/4 plus the OS_2 and head style bits, all of which the cleaner preserves (it only touches the name table, and keeps 1/2/4). Dropping 16/17 can affect grouping in some desktop apps, but browser weight selection is unaffected.
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.