Skip to content
Start
Live · open it · 05 of 07

Kern

Font pairing scored against measured type data, not vibes.

Kern
Kern in use
By the count

468

Families measured in a real browser

5

Roles: display, text, UI, mono, accent

4

Scored dimensions per pairing

0

Runtime font loads needed to score

01 · The problem

Why this exists at all.

Pairing tools show two typefaces on a card and wish you luck. The recommendation comes from a hand-maintained list of pairs somebody liked, which cannot explain itself, cannot be checked, and cannot tell you why a third face would break the set.

What a build actually needs is a type system: two to five roles, working together, exportable as something a stylesheet or an agent can consume directly.

02 · The approach

The decisions, and what they rule out.

01

Measure the catalogue once, in a real browser

Every family was rendered and measured, x-height ratio, character width, ink density, and the numbers ship inside the bundle. Where a family carries no metrics, they are derived from `actualBoundingBoxAscent` on a live canvas. No runtime font loading to compute a score, and no guessing from a name.

02

Score on relationships, then show the reasoning

A pairing scores on classification contrast, x-height rhythm, width rhythm and typographic colour. The reasoning is worn openly: chips under the display slot read things like 'x-height rhythm 0.89 · close' and 'width rhythm 1.05'. A score with no visible derivation is an opinion with a number stuck on it.

03

Deal, don't recommend

Repeat calls return different pairs by design. The tool is not claiming one correct answer exists; it is claiming these pairs satisfy the measured constraints, and here are the numbers so you can disagree.

03 · What testing found

The things thinking about it did not catch.

Every item below is a real defect, found by measurement, with a commit behind it. They are here because the failures are more informative than the features.

01

Mood words cannot promise typographic classification

The catalogue carries usage tags, not classifications. A 'geometric' filter therefore means sans-over-sans, not geometrically-classified faces, and until that was caught, the tool was making a promise its data could not keep. It now states the rule each mood actually applied, without implying a precision it does not have.

02

The engine's own advice was checked against the engine

This studio's site needed a free stand-in for a commercially licensed grotesque. Instead of picking by eye, the catalogue was queried and the substitute chosen on measured x-height: 0.750 against the mono's 0.746, a ratio of 0.995. That is the calculation the tool exists to perform, and it held up when used in anger.

03

Superfamilies are the reliable deal

Faces designed together as a family score consistently well, which is unsurprising and worth encoding rather than rediscovering. They were added as a distinct category in the hand rather than left to emerge from the general scoring.

Built with
  • TypeScript
  • Vite
  • Canvas metrics
  • Google Fonts + Fontshare
Still open

Nothing outstanding. It does what it was built to do, and the known limits are described above rather than parked here.

Open it

Free, no account, running right now.

kern-fonts.vercel.app