How to extract every metadata record from a font
- Step 1Drop your font onto the tool — Accepts `.ttf`, `.otf`, `.woff`, and `.woff2` (detected by the file's first four magic bytes, not the extension). WOFF2 is Brotli-decompressed and WOFF is zlib-decompressed in the browser before parsing; TTF and OTF parse directly. There are no options to set — the extractor has a single Process action.
- Step 2Press Process — opentype.js parses the decompressed sfnt and reads the `name`, `head`, `maxp`, and outline tables. The result panel shows three summary metrics — Family, Glyphs, and the number of tables present — and the full JSON below.
- Step 3Read the `names` object — Each populated record appears under its human label, e.g. `"Family": "Inter"`, `"Version": "Version 4.000"`, `"License URL": "https://..."`. Records the font does not populate simply do not appear — the object only contains what was actually present in the binary.
- Step 4Check the structural fields — `units_per_em` (usually 1000 for CFF/OTF, 2048 for TrueType), `num_glyphs`, and `outlines_format` tell you the font's coordinate grid and outline type. `tables_present` reveals capabilities: `fvar` means variable, `COLR`/`CPAL` or `sbix` means colour, `GSUB`/`GPOS` means OpenType layout.
- Step 5Copy or download the JSON — Use Copy to put the JSON on your clipboard, or Download to save it as `<fontname>.metadata.json`. The JSON is pretty-printed with two-space indentation, ready to paste into a ticket, a manifest, or a `diff`.
- Step 6Cross-check against a sibling tool when you need more — The extractor reports the name records and structural basics. For a cryptographic version pin use the [Font Fingerprinter](/font-tools/font-fingerprinter); for ascender/descender/x-height metrics use the [Font Metrics Analyzer](/font-tools/font-metrics-analyzer); for the GSUB/GPOS feature list use the [OpenType Features Inspector](/font-tools/opentype-features-inspector); to confirm the wrapper format from raw bytes use the [Font Format Identifier](/font-tools/font-format-identifier).
What the JSON output contains
Every top-level key in the metadata JSON, with its source in the font and an example value. The extractor reports exactly these fields — there is no OS/2, hhea, or post numeric dump in this tool.
| JSON key | Source | Example value |
|---|---|---|
filename | The uploaded file's name | "Inter-Regular.woff2" |
file_size | Byte length of the uploaded (compressed) file | 30696 |
units_per_em | head.unitsPerEm (the design grid) | 2048 (TrueType) or 1000 (CFF) |
num_glyphs | maxp.numGlyphs | 2548 |
outlines_format | opentype.js outlinesFormat | "truetype" or "cff" |
tables_present | Sorted list of sfnt table tags in the font | ["GPOS","GSUB","OS/2","cmap","glyf",...] |
names | Decoded English name-table records, labelled | { "Family": "Inter", "Version": "Version 4.000" } |
name records the extractor labels
opentype.js exposes name records by symbolic key; the extractor maps each known key to a readable label. Any record opentype.js does not have a key for (e.g. typographic family ID 16/17, WWS names, axis names) is passed through under its raw key if opentype.js surfaces it at all.
| nameID | opentype.js key | Label shown |
|---|---|---|
| 0 | copyright | Copyright |
| 1 | fontFamily | Family |
| 2 | fontSubfamily | Subfamily |
| 3 | uniqueID | Unique ID |
| 4 | fullName | Full name |
| 5 | version | Version |
| 6 | postScriptName | PostScript name |
| 7 | trademark | Trademark |
| 8 | manufacturer | Manufacturer |
| 9 | designer | Designer |
| 10 | description | Description |
| 11 | manufacturerURL | Manufacturer URL |
| 12 | designerURL | Designer URL |
| 13 | license | License |
| 14 | licenseURL | License URL |
| 19 | sampleText | Sample text |
Input format handling and limits
How each input format is read, and the per-file size limit by tier. Limits are checked on the uploaded (compressed) file size before parsing.
| Format | How it is read | Notes |
|---|---|---|
TTF (0x00010000) | Parsed directly | TrueType glyf outlines → outlines_format: truetype |
OTF (OTTO) | Parsed directly | CFF/PostScript outlines → outlines_format: cff |
WOFF (wOFF) | zlib-inflated per table, sfnt rebuilt, then parsed | Same records as the source font |
WOFF2 (wOF2) | Brotli-decompressed via WASM, then parsed | Same records as the source font |
TTC (ttcf) | Rejected | Collections are not supported — split the face out first |
| Free tier | Up to 5 MB per file | Single file, no batch |
| Pro tier | Up to 50 MB per file | — |
| Developer tier | Up to 1 GB per file | — |
Cookbook
Real JSON the extractor returns for representative fonts. Values are illustrative of the shape — your fonts will differ. For batch and CI use see the automation guide; for a field-by-field name-table reference see the name records reference.
A well-populated open-source WOFF2
ExampleAn SIL OFL font typically fills copyright, family, version, manufacturer, designer, and both license records. Note the extractor read the records straight out of the Brotli-compressed WOFF2.
Input: Inter-Regular.woff2
Output (metadata JSON):
{
"filename": "Inter-Regular.woff2",
"file_size": 30696,
"units_per_em": 2048,
"num_glyphs": 2548,
"outlines_format": "truetype",
"tables_present": ["GDEF","GPOS","GSUB","OS/2","cmap","glyf","head","hhea","hmtx","loca","maxp","name","post"],
"names": {
"Copyright": "Copyright (c) 2016-2024 The Inter Project Authors.",
"Family": "Inter",
"Subfamily": "Regular",
"Full name": "Inter Regular",
"Version": "Version 4.000",
"PostScript name": "Inter-Regular",
"Manufacturer": "The Inter Project Authors",
"License": "This Font Software is licensed under the SIL Open Font License, Version 1.1.",
"License URL": "https://openfontlicense.org"
}
}A sparsely-populated foundry TTF
ExampleSome commercial or hand-built fonts populate only the four legacy records the OS needs to install. Records that aren't in the binary simply don't appear in the JSON — the names object is small rather than full of empty strings.
Input: Custom-Display.ttf
Output (names section):
{
"Family": "Custom Display",
"Subfamily": "Regular",
"Full name": "Custom Display Regular",
"PostScript name": "CustomDisplay-Regular"
}
No Version, Copyright, License, or License URL keys appear
because those records were never written into the font.Telling outline format from the JSON
Exampleoutlines_format and units_per_em together identify the outline technology. CFF/OTF fonts almost always use a 1000-unit em; TrueType fonts almost always use 2048. The tables_present list confirms it — glyf/loca means TrueType, CFF (or CFF2) means PostScript.
OTF (PostScript outlines): "units_per_em": 1000, "outlines_format": "cff", "tables_present": [..., "CFF ", "cmap", "head", ...] TTF (TrueType outlines): "units_per_em": 2048, "outlines_format": "truetype", "tables_present": [..., "glyf", "loca", "cmap", ...]
Spotting a variable or colour font from tables_present
ExampleThe extractor does not enumerate axes or colour layers, but the presence of certain table tags tells you the font has those capabilities — useful triage before reaching for a specialised tool.
Variable font → look for fvar (axes) + gvar/HVAR: "tables_present": [..., "fvar", "gvar", "avar", "HVAR", ...] → freeze an instance with /font-tools/variable-font-freezer Colour font → look for COLR+CPAL, sbix, or CBDT/CBLC: "tables_present": [..., "COLR", "CPAL", ...] → strip layers with /font-tools/colour-table-remover
Quick licence triage across a folder
ExampleRun each font through the extractor and capture the License / License URL records into a flat table. Fonts with no License key need their distribution checked manually — the licence may live in a separate LICENSE.txt, not the binary.
filename | Version | License URL ------------------------|------------------|---------------------- Inter-Regular.woff2 | Version 4.000 | openfontlicense.org Roboto-Regular.woff2 | Version 3.011 | apache.org/licenses Mystery-Bold.ttf | (no Version key) | (no License URL key) Mystery-Bold.ttf carries no licence record — verify its source before shipping it. See /font-tools/guides/font-metadata-licensing-compliance
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.
Font has no name records at all
PreservedIf the name table is empty or stripped, the names object comes back as {}. The structural fields (units_per_em, num_glyphs, outlines_format, tables_present) still populate because they come from head/maxp, not name. A nameless font usually won't install cleanly on most OSes — check the source; it may have been over-aggressively subset or its name table removed by a build step.
Records are present in another language but not English
English onlyThe extractor reads each record via opentype.js getEnglishName. A font that stores, say, only Japanese (ja) or platform-Macintosh name records — but no Windows-English ones — may return an empty or partial names object even though the records exist. This is by design: the tool surfaces the English string, which is what most tooling and CSS expect. To see every platform/language record you need a low-level name-table dumper (FontForge, fonttools ttx).
Typographic family (ID 16/17) or WWS names not shown
By designThe extractor labels the records opentype.js exposes by symbolic key. Typographic Family Name (ID 16), Typographic Subfamily (ID 17), WWS names (21/22), and variable-font axis names (256+) are not in the label map. opentype.js may surface them under a raw key, but the legacy Family (ID 1) and Subfamily (ID 2) are what appear as Family/Subfamily. For a full ID-by-ID picture see the name records reference.
Uploaded a TrueType Collection (.ttc)
Unsupported formatCollections (ttcf magic) bundle multiple faces in one file. The extractor's sfnt loader rejects them with an error — it parses single-face TTF/OTF/WOFF/WOFF2 only. Extract the individual face you care about (fonttools ttx, or a desktop editor's 'export face') and run that single TTF/OTF through the tool.
File extension lies about the format
PreservedFormat is detected from the first four bytes (the sfnt/WOFF magic), not the filename. A WOFF2 renamed to .ttf, or a .otf that is really TrueType, is read correctly. If the magic is unrecognised the tool errors with the detected (unknown) magic rather than silently producing garbage.
File exceeds the tier size limit
413-style rejectThe uploaded file size is checked before parsing: 5 MB on free, 50 MB on Pro, 1 GB on Developer. Over the limit, the tool blocks with an upgrade message and does not parse. The check is on the compressed upload — a 4 MB WOFF2 is fine even though its decompressed sfnt is much larger.
Version string format varies wildly by foundry
Opaque stringThe Version record (nameID 5) is free text. You will see Version 1.001, Version 4.000;git-..., OTF 1.020;PS 001.000, and many more. The extractor returns it verbatim — treat it as an opaque identifier, not a parseable semver. For reliable version pinning across silent foundry updates, pair with the Font Fingerprinter.
License record empty but a LICENSE file ships alongside
ExpectedMany open-source families (Google Fonts especially) leave nameID 13/14 thin or empty in the binary and ship the licence in a separate OFL.txt/LICENSE file in the distribution. An empty License key in the JSON is not proof the font is unlicensed — check the upstream package. See the licensing-compliance guide.
Want OS/2 metrics, vendor ID, or italic angle
Use the metrics toolThis extractor reports the name records plus units_per_em, num_glyphs, outlines_format, and tables_present — it does not dump OS/2 ascender/descender/x-height/cap-height, the achVendID vendor code, or the post-table italic angle. For vertical metrics use the Font Metrics Analyzer; for the OpenType feature set use the OpenType Features Inspector.
Subset web font with most records removed
ExpectedAggressive subsetters (and some build pipelines) trim the name table down to the few records a browser needs. A production WOFF2 may legitimately return only Family, Subfamily, and Version. That is normal optimisation, not corruption — the full record set lives in the foundry's source file, not the shipped subset.
Frequently asked questions
Which name-table records does the extractor decode?
It labels these by symbolic key: Copyright (0), Family (1), Subfamily (2), Unique ID (3), Full name (4), Version (5), PostScript name (6), Trademark (7), Manufacturer (8), Designer (9), Description (10), Manufacturer URL (11), Designer URL (12), License (13), License URL (14), and Sample text (19). Only records actually present in the font appear — there are no empty placeholders. Modern typographic-family records (16/17) and axis names (256+) are not in the label set.
Can I extract metadata from a WOFF2?
Yes. The tool decompresses the WOFF2 Brotli stream with a WASM decoder, rebuilds the sfnt, and parses the same name/head/maxp tables you would get from the source TTF. WOFF is handled the same way via zlib. The records are identical because WOFF/WOFF2 are lossless wrappers — they don't strip metadata, only compress the bytes.
Does it dump the OS/2, head, hhea, and post tables?
No — not as numeric field dumps. From head/maxp it reports units_per_em and num_glyphs, and it lists which tables are present in tables_present, but it does not expand OS/2 metrics (ascender, descender, x-height, cap-height, achVendID) or post-table fields (italic angle). For those, use the Font Metrics Analyzer.
What does outlines_format tell me?
truetype means the font uses quadratic glyf outlines (typically 2048 units-per-em); cff means PostScript/Type 2 charstrings in a CFF table (typically 1000 units-per-em). It's the cleanest single field for distinguishing a TTF-style from an OTF-style font regardless of the file extension or wrapper.
Why is the names object empty for my font?
Two common causes: (1) the name table was stripped or never populated; (2) the font stores name records only in non-English languages, and the extractor reads the English string via getEnglishName. The structural fields still populate in both cases. If you need every platform/language record, use a low-level dumper like fonttools ttx.
What if the font has no name records?
The names object comes back as {}. The rest of the JSON (units_per_em, num_glyphs, outlines_format, tables_present, file_size) is still produced from other tables. A font with no name records usually fails to install correctly on most operating systems, so it's worth checking how the font was produced.
Are there any options to configure?
No. The Metadata Extractor is option-free — you drop a file and press Process. It always returns the same JSON shape. If you need to filter or select fields, do it on the output JSON afterward (e.g. with jq or a spreadsheet).
Is the font uploaded to a server?
No. Parsing happens entirely in your browser tab via opentype.js and the WASM WOFF2 decoder. The font binary never leaves your machine, which matters for unreleased or commercially-licensed faces. The only thing recorded server-side for signed-in users is an anonymous run counter — no file content.
What's the largest font I can extract from?
The per-file limit is 5 MB on the free tier, 50 MB on Pro, and 1 GB on Developer. The check is on the uploaded (compressed) size before parsing, so a small WOFF2 is fine even if its decompressed form is large. The extractor processes one file at a time.
Can I read the licence terms from the font alone?
Sometimes. nameID 13 (License) and 14 (License URL) hold the embedded terms when the foundry populated them. But many open-source families ship the licence in a separate file rather than the binary, so an empty License key isn't proof the font is unlicensed. See the licensing-compliance guide for how to handle this in an audit.
How do I know if a font is variable from the output?
Look at tables_present. An fvar table means the font is variable (it defines the axes); gvar/HVAR/avar are the associated variation tables. The extractor doesn't list the axes themselves — to bake a specific instance to a static TTF use the Variable Font Freezer.
Can I extract metadata from a .ttc collection?
No — TrueType Collections are rejected. The extractor parses single-face TTF/OTF/WOFF/WOFF2 files. Split out the face you need first (fonttools, FontForge, or a desktop editor) and run that single font through the tool.
Can I edit these records in the browser?
No — this tool is read-only. opentype.js can read the name table reliably but its name-table writer produces broken output for some platform/encoding combinations, so editing isn't offered here. To trim records use the Name Table Cleaner (which keeps the safe Windows-English records and rebuilds the table); to rewrite arbitrary records use a desktop editor and re-verify with this extractor afterward.
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.