How to build an icon font catalogue with the glyph inspector
- Step 1Drop the icon font — Any icon font in TTF, OTF, WOFF, or WOFF2 — Font Awesome, Material Icons, Bootstrap Icons, or your own build. The inspector decodes it and walks every glyph.
- Step 2Process and read the records — Each glyph becomes a record. Icons typically sit in the Private Use Area, so most records carry a `unicode` like `U+E001`. `name` holds your icon name when the font's `post`/CFF charset includes names.
- Step 3Skip the structural glyphs — Index 0 (`.notdef`) and any space glyph aren't icons — filter records where `unicode` is `null` or `svgPath` is empty if you only want drawable icons in the catalogue.
- Step 4Derive the selectors — For each icon record, turn `unicode` (`U+E001`) into a CSS escape (`content: "\e001"`) and an HTML entity (``). Both come straight from the hex after `U+`.
- Step 5Render previews from svgPath — Wrap each record's `svgPath` in an `<svg>` using its `viewBox`. That gives a live, scalable preview per icon for the catalogue page — independent of whether the icon font itself is loaded.
- Step 6Export and feed your docs — Download the `<stem>.glyphs.json` and transform it into your docs format (a table, Storybook stories, an MDX grid). On the next font release, re-run and diff against the previous JSON.
From a glyph record to icon catalogue fields
What you compute for each catalogue entry from a single inspector record. The escape and entity are derived from the unicode field, not emitted directly.
| Catalogue field | Source | Example |
|---|---|---|
| Icon name | name | home (or null if post/charset stripped) |
| Codepoint | unicode | U+E001 |
| CSS escape | derive from unicode | content: "\e001"; |
| HTML entity | derive from unicode |  |
| Preview SVG | svgPath + viewBox | <svg viewBox="0 0 1000 1000"><path d="..."/></svg> |
| Width / box | advance, xMin..xMax, yMin..yMax | advance 1000; box 50..950 × 0..900 |
What to expect from common icon fonts
Behaviour you'll see in the inspector output for popular icon fonts. Names depend on whether the font ships a post table / CFF charset.
| Icon font | Codepoints | Names in output? |
|---|---|---|
| Material Icons | PUA (U+E000+) and some standard | Usually yes — ships descriptive glyph names |
| Font Awesome | PUA (U+F000+) | Often yes for the desktop build; web subsets may strip post |
| Bootstrap Icons (font build) | PUA | Depends on the build; check name for null |
| Your own (IcoMoon / Fantasticon) | PUA from your start codepoint | Yes when the tool writes glyph names; verify after each build |
| A stripped/optimised web build | PUA | Often null — post removed for size; fix the build if you need names |
Cookbook
Turning inspector output into catalogue artifacts. The icon font here uses the PUA from U+E000.
A single icon record
ExampleA 'home' icon in a custom icon font. PUA codepoint, descriptive name from the post table, and a path you can render.
{
"index": 1,
"name": "home",
"unicode": "U+E001",
"advance": 1000,
"xMin": 80, "xMax": 920,
"yMin": 0, "yMax": 880,
"svgPath": "M500 80 L920 460 ...Z",
"viewBox": "0 0 1000 1000"
}Deriving CSS and HTML selectors
ExampleFrom the unicode field you produce both the CSS pseudo-element escape and the HTML entity — the two ways developers reference an icon-font glyph.
unicode "U+E001" → hex "e001"
CSS:
.icon-home::before { content: "\e001"; }
HTML:
<span class="icon"></span>
Both select the same glyph the inspector listed.A catalogue table row
ExampleMap each drawable record to a docs table row. Filter out .notdef and any glyph with null unicode or an empty path so only real icons appear.
| Preview | Name | Codepoint | CSS | |---------|------|-----------|----------| | <svg> | home | U+E001 | \\e001 | | <svg> | user | U+E002 | \\e002 | | <svg> | gear | U+E003 | \\e003 | (Preview is the svgPath rendered inline.)
Diffing two font versions
ExampleRun the inspector on v1 and v2, keep the JSON, and diff on the (name, unicode) pairs to see what changed between releases.
v1 icons: home(E001) user(E002) gear(E003)
v2 icons: home(E001) user(E002) gear(E003) bell(E004)
Diff → ADDED: bell (U+E004)
REMOVED: (none)
RENAMED: (none)
The catalogue auto-updates from the v2 JSON.Icon font with no names (post stripped)
ExampleAn optimised web build dropped the post table, so every record has name: null. The catalogue would be nameless — a signal to fix the build, or fall back to index/codepoint-based labels.
{
"index": 1,
"name": null, ← post table stripped
"unicode": "U+E001",
"advance": 1000, ...
}
Fix: re-export keeping glyph names, OR label icons
as "icon-e001" from the codepoint until the build
is fixed.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.
Icon font ships without a post table
Names missingMany optimised icon-font web builds strip the post table to shave bytes, so opentype can't recover names and every record's name is null. Your catalogue would list icons by codepoint only. Either re-export the font keeping glyph names, or generate fallback labels like icon-e001 from the unicode value until the build is fixed. Confirm post presence with the font-metadata-extractor.
.notdef and space appear in the records
Filter expectedIndex 0 (.notdef) and any space glyph are real glyphs in the font but not icons. They'll show up in the output with unicode: null (notdef) or an empty svgPath (space). Filter records where unicode is null or svgPath is empty so your catalogue contains only drawable icons.
Icon set larger than 5,000 glyphs
Truncated at 5,000The inspector caps at 5,000 records on every tier. Almost no icon font is that large, but a mega-pack with multiple weights merged into one file could exceed it. Check sampled vs total_glyphs in the header; if truncated, split the font by weight/style and inspect each, or run an opentype walk in a script.
Glyph mapped to a standard codepoint, not PUA
By designSome icon fonts (notably Material Icons in ligature mode) also map glyphs to standard codepoints or rely on ligatures rather than PUA escapes. The inspector reports the primary unicode it finds; if an icon is reached by a ligature instead of a codepoint, the glyph may show unicode: null. Document the intended access method (escape vs ligature) alongside the catalogue.
Two icons share one glyph (aliasing)
Primary onlyIf a build aliases two names to the same glyph, or maps several codepoints to one shape, the inspector reports a single primary unicode per record. Aliases mapped to extra codepoints won't each get their own record. For an exhaustive codepoint listing, cross-check the full cmap via the character-coverage-map.
Animated or multi-colour icons
Static outline onlyThe inspector reads outline geometry. Animation lives in CSS/SMIL outside the font, and multi-colour glyphs use COLR/CPAL or SVG tables that the per-glyph svgPath (a single monochrome outline) doesn't capture. The catalogue preview shows the base outline; layer colour and motion separately in your docs.
Variable icon font (weight axis)
Default masterA variable icon font's svgPath reflects the default axis position only — opentype doesn't interpolate gvar. To catalogue a specific weight (e.g. a 600-weight icon set), freeze the instance first with the variable-font-freezer, then inspect.
Confidential brand icon font
Stays localParsing is in-browser with a 0 bytes uploaded badge, so an unreleased or licence-restricted icon font never reaches a server. You can build the catalogue for an internal design system without exposing the binary.
Frequently asked questions
Does the inspector produce a visual icon gallery?
No — it produces JSON. There's no built-in gallery and no PNG export. But each record includes a real svgPath plus viewBox, so you render the gallery yourself: wrap each path in an <svg> with its viewBox and you get a scalable preview per icon. The catalogue's visuals come from the paths the inspector hands you, on whatever page you build.
Where do the icon names come from?
From the font's post table (TrueType) or CFF charset (OTF), surfaced as each record's name. If your build keeps glyph names, you get home, user, gear, etc. If the build strips post to save bytes, name is null and you'll need to fix the export or fall back to codepoint-based labels.
How do I get the CSS escape for an icon?
Derive it from the record's unicode. U+E001 → strip the U+ → content: "\e001"; in your ::before rule. The HTML entity is the same hex: . The inspector gives you the codepoint; the escape and entity are mechanical transforms of it.
What about Material Icons specifically?
Material Icons usually ship descriptive glyph names, so the inspector surfaces name values like home and search. Note that Material Icons can be accessed by ligature as well as by codepoint; if an icon is ligature-only, its glyph may show unicode: null. Document which access method your team uses alongside the catalogue.
Can I re-run when icons are added?
Yes — drop the new font version, regenerate the JSON, and diff it against the previous run on the (name, unicode) pairs. Added, removed, and renamed icons fall out of the diff, so your catalogue stays in lockstep with the binary instead of drifting.
Can I extract pure SVG components instead of using the icon font?
Yes. Each record's svgPath plus viewBox is a complete, render-ready outline. Many design systems now ship icons as tree-shakeable SVG components rather than a monolithic icon font — the inspector's path output is exactly what you need to generate one .svg/.tsx per icon and drop the font entirely.
How do I exclude non-icon glyphs from the catalogue?
Filter out index 0 (.notdef) and any glyph whose svgPath is empty (space and control glyphs). If your icons are PUA-encoded, you can also keep only records whose unicode falls in U+E000–U+F8FF. That leaves just the drawable icons.
What about animated icon fonts?
The inspector reads static outlines. Animation lives in CSS or SMIL, outside the font binary, so the svgPath is the still shape. Your catalogue preview shows that shape; any motion is layered on separately in your component or CSS.
My icons are multi-colour — does the path capture that?
No. Colour glyphs use COLR/CPAL or an SVG-in-OpenType table, but the inspector's per-glyph svgPath is a single monochrome outline. You'll get the base shape, not the colour layers. For full-colour previews you'll need the source artwork or a renderer that understands the colour tables.
Is there a limit on how many icons it'll list?
It serialises up to 5,000 records on every tier. That's far more than any normal icon font. If a merged multi-weight pack somehow exceeds it, the header's sampled will be below total_glyphs — split the pack by weight and inspect each part.
Will my confidential icon font be uploaded?
No. It's parsed in your browser; the result panel shows 0 bytes uploaded. You can catalogue an unreleased or licence-restricted brand icon font without it ever leaving your machine.
How do I count icons or check coverage across blocks?
For a straight count use the glyph-count-analyzer; for which Unicode blocks (including the PUA) the font touches, use the character-coverage-map, which scores against 346 blocks. The inspector is for per-icon detail; those two give you the totals and the block-level view.
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.