Guide · 11 steps · ~55 min
Variable fonts.
A variable font is a single file that contains multiple master designs and a way to interpolate smoothly between them. Instead of shipping Regular, Medium, Bold, and Black as four separate files, you ship one file with a weight axis. The rasteriser computes the in-between weights on demand. This guide covers axes, masters, instances, Patens's 2D variation explorer, and the export path.
Variable fonts are the dominant modern format on the web — Google Fonts shifted its catalog to variable in 2022 — and Patens supports designing, previewing, and exporting them entirely in the browser.
- 1
What a variable font is
A variable font is a single font file that contains multiple master designs and a way to interpolate smoothly between them. Instead of shipping Regular, Medium, Bold, and Black as four separate files, you ship one file with a weight axis and the rasteriser computes the in-between weights on demand. The result: one file covers a continuous design space rather than a fixed set of discrete styles, fewer HTTP requests on the web, and the ability to tune type to context (slightly heavier on a low-contrast background, slightly narrower in a tight column).
A variable font is also a valid static font — every OpenType variable file works as a Regular when the renderer ignores its axes. You're not picking one or the other.
- 2
Axes
An axis is a single dimension along which the design varies. The five standard registered axes are weight (wght, default 400), width (wdth, default 100), slant (slnt, default 0), italic (ital, 0 or 1), and optical size (opsz). Custom axes are allowed (a 4-letter tag prefixed by uppercase, e.g. GRAD for grade), but renderers only recognise the registered ones for CSS. Each axis has a min, default, and max value.
Audit code axis-range-invalid fires when min ≥ default ≥ max isn't satisfied. The default should be the most common reading weight (400 for wght), not the midpoint of the range.
- 3
Masters
A master is one drawn instance of every glyph at a specific point in design space. A weight-axis-only font needs at least two masters (one at the lightest end, one at the heaviest); the renderer interpolates between them. A two-axis font (weight + width) needs masters at the four corners of the rectangle at minimum, optionally with masters inside the rectangle to control intermediate behavior. Patens stores each master as a sibling project linked into a Family record.
Every glyph must have the same number of contours and the same number of points in the same order across all masters. Audit code master-contour-count and master-point-count fire when they don't.
- 4
Adding your first axis
In Patens, axes are defined at the Family level. Open /family/[id] → Designspace, click Add axis, pick wght, set min 100, default 400, max 900. The Family now has a wght axis but no masters along it. Drawing a sibling project and marking it as the "wght 400" master gives the family its first masters; a second sibling at wght 900 completes the line.
Start with one axis (wght is the canonical first axis). Adding a second axis triples the work — every new master needs to be drawn at multiple axis positions.
- 5
Where masters live in design space
A master's position in design space is its coordinate on each declared axis. A wght-only font: master A is at wght 400, master B at wght 900. A wght+wdth font: master A at (400, 100), B at (900, 100), C at (400, 75), D at (900, 75). Patens lists every master with its axis coordinates on the Designspace page; the 2D variation explorer (Cmd+E from any axis page) lets you drag through the rectangle and see the interpolation live.
master-axis-out-of-range fires when a master's coordinate is outside the declared min/max of the axis. master-orphan-axis fires when a master references an axis the family no longer declares.
- 6
Instances
An instance is a named point in design space that the operating system surfaces as a style — what the user sees in the font menu when picking "Regular" or "Bold". A wght-only font usually has 9 instances: Thin (100), ExtraLight (200), Light (300), Regular (400), Medium (500), SemiBold (600), Bold (700), ExtraBold (800), Black (900). The instances are pointers into the design space; they don't need to coincide with masters.
Audit code no-instances fires when a family has axes but no instances. Without instances, app font menus only show "Regular" and users can't pick weights from the dropdown — only via CSS font-variation-settings.
- 7
The 2D variation explorer
For families with two or more axes, Patens ships a 2D explorer — a draggable surface where each axis is a dimension and the current sample text re-renders live as you drag. It's the fastest way to see how the interpolation behaves at points your instances don't cover. The explorer also shows where your masters and instances are placed, so you can spot gaps or clusters at a glance.
Drag with Shift to constrain to one axis. Drag with Cmd to snap to nearest 10-unit grid.
- 8
Common gotchas
Variable fonts are interpolation, not magic. The two masters set the endpoints; everything between is a linear blend. If your Thin and Black are too different in stroke contrast or letter proportion, the intermediate weights look wrong. The fix is to add a master in the middle to anchor the interpolation. Patens flags master-empty when a glyph is drawn at one master but missing at another — interpolation needs every master to have every glyph.
Drawing 88 glyphs at 2 masters is 176 glyph designs. Plan accordingly — variable fonts are 2-4× the work of a static family.
- 9
Exporting a variable font
On export, Patens compiles the masters into an OpenType variable font (.otf with gvar / HVAR tables, or .woff2). The output works in every modern browser via @font-face, in Adobe apps via the CSS-equivalent UI, and in InDesign 2020+. Instances appear in the OS font menu (macOS Big Sur+, Windows 10+). The .font.json export preserves the full designspace so a collaborator can open and continue from where you left off.
CSS hookup: font-family: "YourFont"; font-variation-settings: "wght" 525, "wdth" 87;
- 10
Importing a designspace from Glyphs, FontLab, or RoboFont
Patens supports designspace v5 round-trip — the XML interchange format that Glyphs, FontLab, RoboFont, and Fontmake all read and write. You can import an existing .designspace file (axes + sources + instances will populate; you import the UFOs separately) and export back to designspace XML when you want to continue elsewhere. The mapping is near-1:1 to Patens's Axis / Master / VariableInstance records.
parseDesignspaceXml + designspaceFromProject in src/lib/font/designspace.ts. Round-trip is structurally lossless for axes, sources, and instances — glyph data flows through the existing UFO import/export pipeline.
- 11
Pre-launch audit codes for variable fonts
Patens's 105-code audit module now includes three checks tuned specifically for variable-font hygiene. axis-range-extreme (info) flags axes whose range exceeds the conventional comfort zone (wght > 800, wdth > 100, opsz > 50pt, slnt > 30°) — extreme masters often need an intermediate to anchor the interpolation. master-too-close (warn) flags masters within 5% of each other in designspace — either redundant or a deliberately tight intermediate pair. stat-missing (warn) flags variable fonts with axes but no familyAxes set, which means STAT generation at export-time uses defaults that Windows can misinterpret. Each check fires deterministically and links to its primary literature on /audit/[code].
Full audit reference at /audit. The variable-font codes live in the Designspace axes + Designspace & masters + Variable-font compatibility categories.
Related
The audit-codes reference documents the eleven designspace / variable-font codes. The kerning guide covers how kerning interacts with multi-master families. And the first-font tutorial is the right place to start if you haven't drawn a static master yet.
For deeper background, the Variable Fonts Primer at variablefonts.io is the canonical practitioner-side reading on designing + implementing variable fonts. The fvar chapter of the OpenType spec is the normative reference for the axis + instance machinery Patens's audit checks against.
Patens is in private alpha. Request an invite →