FontPeeker

Look inside a font file.

Drop a .ttf, .otf, .woff or .woff2 and FontPeeker reads its name table, vertical metrics, OpenType features, variable axes and every glyph it contains. The file is parsed in this tab — there is no upload, no account and no server.

Drop a font file

.ttf .otf .woff .woff2

The file is read with the FileReader API and parsed in this tab. It is never sent anywhere — FontPeeker has no server to send it to. The sample is Manrope by Mikhail Sharanda, under the SIL Open Font License.

What FontPeeker reads

It reads the tables, not a preview

name, head, hhea, OS/2, post, cmap, GSUB, GPOS and fvar are parsed with opentype.js, so what you see is what the file declares: the designer, the licence string, the embedding bits, the units per em and the real glyph count.

It answers the coverage question

The cmap is checked against Unicode blocks and against alphabets people actually set: Russian, Ukrainian, Serbian, Greek, Central European, typographic quotes and currency signs. You find the missing Ґ before your reader does.

It writes the CSS for you

The CSS tab emits an @font-face rule with the correct format keyword, the weight range taken from the fvar axis, and the font-variation-settings and font-feature-settings that match the sliders and switches you just moved.

What is inside a font file

A font file is a database. The name table holds the family, the style, the version, the designer, the foundry and the licence text the vendor chose to ship; OS/2 holds the weight class, the width class, the x-height, the cap height and the fsType bits that say whether the font may be embedded at all; cmap lists every character the font can actually set; GSUB and GPOS hold the ligature, small-caps, figure-style and kerning rules; fvar describes the axes a variable font can interpolate along. FontPeeker opens all of them and lays the values out as a plain sheet so you can read a font the way you would read a spec.

Most font viewers ask you to upload the file first. That is an odd thing to accept for a licensed asset you may not be allowed to redistribute — and it is unnecessary, because browsers have had everything needed to do this locally for years: the File API to read the bytes, the FontFace API to render them, canvas to draw outlines, and WebAssembly to decompress the Brotli stream inside a WOFF2. FontPeeker uses exactly those. Open the network tab while you use it: after the page has loaded, nothing leaves.

Frequently asked questions

Is my font uploaded anywhere?+

No. The file is read with the browser's File API and parsed by JavaScript running in your tab. FontPeeker is a static site with no upload endpoint, no database and no analytics, so there is nowhere for the file to go. You can watch the network panel while you work: after the page and its assets have loaded, nothing else is requested except the sample font if you ask for it.

Does it read WOFF2, or only the desktop formats?+

It reads WOFF2 in full. A WOFF2 file is an sfnt font whose tables have been transformed and compressed with Brotli, so it has to be decompressed before any table can be parsed. FontPeeker loads a small WebAssembly decompressor (the wawoff2 build, with the wasm embedded in the script) the first time you open one, rebuilds the sfnt in memory and then parses it exactly like a .ttf. TrueType collections (.ttc and .otc) are the one container it will not open — extract a single face first.

Can I move the variable axes and see the result?+

Yes. If the file has an fvar table, the Axes tab gives every axis a slider labelled with its tag, its range and its default, and the specimen re-interpolates as you drag. The designer's named instances are listed as buttons, so you can jump to the exact coordinates a font menu would offer. Whatever you set is written into the font-variation-settings line on the CSS tab.

Why is the glyph count bigger than the number of characters?+

Because glyphs and characters are not the same thing. The cmap table maps code points to glyphs, but a font also carries glyphs that no code point points at: the second half of a ligature set, small-cap and oldstyle variants, positional forms, components reused inside accented letters, and the .notdef box. FontPeeker shows both numbers — “glyphs” from the maxp table and “mapped characters” from cmap — and the glyph browser lets you page through the unmapped ones too.

How do I check whether a font really covers Cyrillic?+

Open the Characters tab. The top block tests the cmap against alphabets people actually set — Russian, Ukrainian and Serbian, Greek, Central European, currency signs and typographic quotes — and lists the exact characters that are missing. Below it, every Unicode block the font touches is shown with a covered-of-total count. A font advertised as “Cyrillic” very often has the Russian alphabet and nothing else, so Ґ, Є, І, Ї, Ђ and Џ are the letters to look for.

Is the generated @font-face rule ready to use?+

Nearly. The family name, the format keyword, the style, and the weight range come from the file itself — a variable font gets font-weight: 200 800 rather than a single value, which is what lets one file answer every weight in between. What FontPeeker cannot know is where you will host the file, so the src path is just the file name; change it to your own URL. For the web you will normally want to serve WOFF2 rather than the .ttf you inspected.

Can I trust the licence information it shows?+

Treat it as a strong hint, not as the licence. Everything under “From the name table” is copied verbatim from name IDs 0, 7, 10, 13 and 14 — strings the vendor typed into the font. They are usually accurate and often link to the real agreement, but they are not updated when a licence changes and they are not binding. The fsType field in OS/2 is machine-readable and more specific: FontPeeker translates it into installable, preview-and-print, editable or restricted, and warns you when embedding is limited.

How large a font can it open?+

The hard limit is 64 MB, which is far beyond any normal text font — a full CJK family with tens of thousands of glyphs is usually 10–20 MB. Parsing happens on the main thread, so a very large file takes a second or two and the tool tells you which step it is on. The glyph browser pages 96 glyphs at a time, so a 60,000-glyph font stays responsive.

Does it work offline?+

Once the page is open, yes — parsing, rendering, the glyph outlines and the CSS all run locally. Two things are fetched from this site on demand: the sample font, if you click it, and the WOFF2 decompressor, the first time you open a .woff2. Load the page while you have a connection and both of those will be in the browser cache.