graf

Typography, taken apart

the message

A loupe and pliers for typography. Drop a font file and see what it actually says about itself — its anatomy, kerning, the designer provenance, the optical signatures. Then flip it forward: transform every glyph, or blend two outlines, and walk away with a real .otf.

→ Launch graf web only · no install · fonts never leave the browser

heads up graf is an experimental research artifact, not production software. Use it for curiosity, teaching, and play. We’re not responsible for how you use it, what it outputs, or whether its outputs break your stuff.

Mix tab with a three-source simplex — drag the dot to rebalance weights between Source Han Serif CN, Apple Chancery, and Roboto Light; every glyph’s outline is re-interpolated in real time

An intelligent viewer for looking at letterforms and the files that hold them. And a designtoy. Not really a font identifier. Not really a type-design tool. A prism you can use to mess with your fonts.

Built through Iterative LLM Co-Authorship — Phil Renato and Claude, trading drafts until the readings said what they meant. graf is a design thesis applied to itself: four wordmark faces at once. Each section cites the source it learned from, every derived font preserves every contributor’s credits in its own name table.

On the way in, graf parses the file through opentype.js and reads every table the designer actually shipped. The family, the foundry, the copyright, the license, every OpenType feature, every GPOS kerning pair, every variable-font axis. None of it is guessed — there’s no model in the loop here. The file is held in the browser’s memory and nowhere else. 

On the way out, if you want one, graf drops a new font on you. Forge walks every glyph’s path commands, applying transforms. Mix interpolates outlines between two sources, or composes range-by-range across several. The output is a functional .otf — it installs in your operating system, sets type in Word, loads in Glyphs. Every source font’s copyright, license, designer, and foundry records travel verbatim in the output’s name table, plus a description line recording the transformation. Most licenses require that. Respecting the source is also just the posture.

graf also reads the license on the way in. A font that declares itself remixable gets forged and mixed. A font whose license forbids further modification, or forbids handing the modified file along, stays inspectable in Dig — but the write path is closed. A font graf writes is itself a remix, and the person who downloads it should be free to remix it in turn. If the source breaks that chain, graf declines to extend it.

Everything on screen is computed from the loaded file.
Nothing from nothing gets nothing.

Dig tab showing the Forge specimen panel, Hamburgefonstiv 0123, pangram, and name-table attribution for Lao Sangam MN
I. On the way inDig’s Forge specimen — live preview of a cut, name-table attribution preserved at the bottom.

The Canon

Twenty-three lessons in seven kinds — anatomy, pair, line, block, contrast, scale, variable. Twelve anatomy lessons teach against a fixed reference face so the labels stay pedagogically correct — a double-story a has different anatomy than a single-story a, a humanist O has a stress axis where a geometric O doesn’t, and one reference teaches it right. Eleven further lessons speak directly to your file: kerning, ligatures, leading, measure, figures, small caps, color-of-type, and more, through live interactive demonstrations. Lesson 21 renders the same letter at five point sizes and snaps the opsz axis (if the file ships one) to each, surfacing real optical compromises. Lesson 24 compares a mechanically skewed roman with a true italic, so you can see which files redraw and which only lean. A final one reads the font’s variable axes and gives you a slider per axis.

Every lesson cites a source. The sources are books (Bringhurst, Hochuli, Noordzij, Beier, Ruder, Updike, Catich, Unger, Cheng, Tselentis), essays (Warde’s Crystal Goblet, Morison’s First Principles), and published work by living practitioners.

Dig

Font-Book-level inspection — hero specimen, waterfall, every OpenType feature as a toggle, every glyph in a virtualized table, per-glyph path detail with on-curve and off-curve points, advance-width box, metric lines. 

Fingerprint. Rasterizes O, H, e, n, o, a to a 240×240 offscreen canvas and derives six measurements from the pixel runs and the font’s own tables: stress-axis angle (from the thinnest points of the O bowl), x-height ratio (from the os/2 table, raster fallback), stroke contrast (H stem ÷ crossbar), aperture at the e terminal, counter density (flood-filled across lowercase), and overshoot (O vs. H, in font units).  Downloads as a standalone SVG card with a six-axis radar chart.

Pair Atlas. Enumerates every kerning pair the font ships — ≈6,400 candidate pairs queried through opentype.js’s getKerningValue. Filters to non-zero, sorts by magnitude, tightest, or loosest. Interactive preview with the font-shipped value plus ±300u adjustment. An empty atlas is also a verdict: some files simply don’t ship kerning.

Forge

Programmatic remix. Walks every glyph’s path commands. Fourteen controls in five groups. Shape: slant, stretch X, stretch Y. Anatomy zones: x-height scale, ascender pull, descender pull — pivoting on the font’s real metric lines rather than the bounding box. Curves: rebuild (de Casteljau subdivision to add anchors, deterministic flattening to remove them) and smooth (cubic handles normalized toward 35% of chord length, taming lumpy outlines). Rough stuff: wave and seeded perturbation. Letter-level chaos: wobble Y, slant jitter, width jitter — each glyph pulls its own value from a seeded pool so the text varies letter-by-letter while every letter stays internally coherent.

Live preview compiles only the ≈100 characters on screen — stays fluid on 50,000-glyph files. Full-font compile runs only on download, with a visible progress banner. Source name records travel into the output verbatim.

Mix

Drop two or more fonts, up to five. Blend interpolates outlines: for every shared codepoint each source glyph is sampled as a dense polyline per contour, contours are paired by signed area and size, arc-length-resampled to a common point count, rotationally aligned, linearly interpolated at the slider value, and refit as a cubic Bezier via chord-length-scaled Catmull-Rom. Real cubic commands out, not a CSS effect. Three-plus sources get a simplex polygon with barycentric (or inverse-distance) weights.

Pick composes range-by-range across fifteen canonical Unicode blocks. B from Bodoni, g from Garamond, digits from Space Grotesk. Forge transformations stack on top of either mode. Every contributor’s copyright, license, designer, and foundry land in the output’s name table.

The Canon — lesson on the lowercase n with anatomy labels (shoulder, stem, counter, x-height) positioned on the glyph Pair Atlas showing every shipped kerning pair of Lao Sangam MN ranked by magnitude Forge tab — source-vs-forged comparison of A, g, Q and & with heavy perturbation applied

Canon · Pair Atlas · Forge

graf reads .ttf, .otf, .woff, and .woff2. Internally it parses the OpenType tables directly: name (identity and attribution), os2 (vertical metrics, codepage and unicode ranges), fvar (variable axes), GSUB (feature substitutions such as liga, smcp, onum), GPOS (pair and kern positioning), the kern table (legacy), and every glyph’s path command set.

graf writes .otf — CFF-flavored OpenType — via opentype.js’s toArrayBuffer. Output should install on macOS, Windows, and Linux and opens in every text-setting application this author has tested. Round-tripping a font through Forge with identity transforms does not produce a byte-identical file: opentype.js re-serializes via CFF, so a TrueType (glyf) input comes out CFF. Not a bug, but a caveat.

Five centuries of people arguing about the same twenty-six letters. The app itself is a few thousand lines of TypeScript. The concepts inside it are older and harder than the code. The four-surface structure (Form → Text → Experimentation) owes a debt to Jason Tselentis’s three-part framing in Type, Form & Function (Rockport, 2011); we use his "Play Principle" as a named permission for what Forge and Mix do.

c. 1450 · Mainz
Johannes Gutenberg cuts type on metal bodies sized before the letterforms are drawn. The grid precedes the letter. The 42-line Bible follows in 1454–55, already shipping dozens of ligatures and abbreviation marks to fit a precise line length.
1470 · Venice
Nicolas Jenson cuts the first fully-resolved humanist roman. The model for every Garamond, Bembo, Sabon, and Minion that follows.
1501
Francesco Griffo cuts the first italic for Aldus Manutius. A new direction for running text.
1757 · Birmingham
John Baskerville’s press begins printing: transitional romans enabled by smoother paper and better ink.
1810s · London
Vincent Figgins and Robert Thorne cut fat-face and “Egyptian” slab-serif types for commercial display printing. The first typefaces designed primarily to advertise rather than to read.
1925–32
Jan Tschichold, Elementare Typographie (1925). Paul Renner, Futura (1927). Eric Gill, Gill Sans (1928). Stanley Morison and Victor Lardent, Times New Roman (1932). Modernism and revival argue on adjacent pages.
1957
Adrian Frutiger’s Univers for Deberny & Peignot; Max Miedinger’s Neue Haas Grotesk for the Haas foundry. The latter is renamed Helvetica in 1960 for Stempel.
1978 · Cambridge, Mass.
Matthew Carter delivers Bell Centennial — four cuts of a single face, each optically tuned for the AT&T phone book at its own size. A public-utility typeface.
1985
Gerrit Noordzij, De streek: the theory of writing as stroke, the axis of the pen as the organizing principle of the letter.
2016
OpenType 1.8 is jointly announced by Adobe, Apple, Google, and Microsoft. Variable fonts ship one file with a continuous design space inside. Fraunces, Recursive, Inter, Roboto Flex, Amstelvar extend the idea beyond the registered weight / width / optical-size axes.
graf Fingerprint section showing the loaded font's six measured signatures as a radar chart with a three-word voice and Vox-style classification
Fingerprint · quantified type DNASix measurements rasterized from O / H / e / n / o / a. A three-word voice and a classification emitted from the numbers. Downloads as an SVG card.
Experimental · no warranty · use at your own risk

graf is an experimental research artifact produced through Iterative LLM Co-Authorship. It is not production software. It is not tested, certified, or supported for professional, commercial, safety-critical, or regulated work. It may produce output that looks plausible but is wrong. It may break. It may crash your browser tab. Your font file stays in your browser; nothing is uploaded or retained, but we make no other promises.

By using graf you accept that: you are responsible for what you do with it, what you do with its output, and whether any of its output fits your purpose. We are not liable for any damage — to a project, a file, a font license you might be obliged to, a system, a deadline, a reputation, or anything else — arising from your use of the app or any artifact it writes. If any of that is a problem for your use case, don’t use graf for that use case.

graf is monolingual — Latin alphabet, English reading context — because applying Latin anatomy to Thai, Arabic, Devanagari, Hangul, or CJK would be reductive and often wrong. It reads each font’s license well enough to refuse writes against sources that forbid further remixing; it does not otherwise certify type classifications, validate licenses, replace Glyphs or FontLab, or tell you whether shipping a derivative is clean. The Fingerprint’s labels are heuristics. It can be wrong, especially on display or icon fonts.

graf cites books, living practitioners, foundries, podcasts, and institutions throughout its Canon sources and Concordance. These are influences, not endorsements. Typeface and foundry names are trademarks of their respective owners; their mention here is nominative fair use. If a citation is inaccurate or you’d rather not appear in it, Phil will remove it on request — write to philrenatoatgmail.

The long version of all of this — what graf does, what it doesn’t, script scope, attribution posture, trademarks, copyrights, how your font file is handled — lives in the Legal panel inside the app. Reachable from the footer next to About, Help, and Concordance.

Open it on a laptop. The Canon sidebar, the Pair Atlas grid, and the Fingerprint’s radar all need horizontal room to feel right. It runs on a phone — you can still inspect a file, read its credits, scrub a slider — but it’s feature-deprived there, and iOS Safari doesn’t pass drag-and-drop events. Use the picker button. For the full thing, use a keyboard and a real display.

No install. Nothing to download. Your fonts never leave your browser. No account, no telemetry, no storage. Reload the page and every loaded font is gone. Honestly, that’s kind of the point.

Built through Iterative LLM Co-Authorship — Phil Renato and Claude, trading drafts until Phil hit a sleep window and Claude hit a context window.

→ Launch graf runs in the browser · desktop recommended