Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
367 changes: 367 additions & 0 deletions blog/2026-04-14-formula-v5.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,367 @@
---
title: "Fontist Formula v5: multi-format and variable font support"
description: "Formula v5 adds explicit schema versioning, multi-format resources, variable font metadata, and import provenance for Fontist formulas."
authors:
- Ronald Tse
- Hassan Akbar
date: 2026-04-14
---

# Fontist Formula v5: multi-format and variable font support

<BlogByline />

Fontist formulas have reached version 5.

This release modernizes the formula schema for today's font ecosystem, where a
single family can be available as desktop fonts, web fonts, static files,
variable fonts, and source-specific system fonts.

The main change is structural: Formula v5 describes what each resource contains
instead of treating every formula as a single download with implicitly-known
font files.

## What formulas do

A Fontist
[font formula](https://www.fontist.org/formulas/)
is a YAML file that tells Fontist where a font comes from, what files are
available, and how those files map to installable font styles.

Formula v4 worked well for the earlier Fontist model: most formulas described
one downloadable package, usually an archive containing desktop font files.

That model is no longer enough. Google Fonts, macOS supplementary fonts, SIL
fonts, and other sources increasingly expose the same family through different
file formats and different font technologies. Formula v5 adds the metadata
Fontist needs to make those differences explicit.

## From implicit to explicit

Formula v4 did not declare its schema version. Formula v5 does:

```yaml
---
schema_version: 5
name: Courier Prime
description: Courier Prime
homepage: https://quoteunquoteapps.com
```

If `schema_version` is missing, Fontist continues to treat the formula as a v4
formula. Existing private and custom formula repositories therefore keep
working.

The explicit version field matters because it gives Fontist a deterministic way
to choose schema behavior. New fields can be added to v5 without changing how
older formulas are interpreted.

## Resources now describe formats

In v4, a resource was usually named after the download itself:

```yaml
resources:
Courier_Prime.zip:
urls:
- https://quoteunquoteapps.com/courierprime/downloads/courier-prime.zip
sha256: d5d4faf1bee0d1f52bab1103cbfdfb354976331c86f999c110c22a098cb12d73
file_size: 193595
```

That structure is still valid for a migrated archive formula, but it does not
tell Fontist what font format the resource provides.

Formula v5 can describe resources by capability. For example, the Abel formula
from Google Fonts provides static TTF and static WOFF2 resources:

```yaml
resources:
ttf_static:
source: google
family: Abel
files:
- https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6VhLPJp6qGI.ttf
urls:
- https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6VhLPJp6qGI.ttf
format: ttf
woff2_static:
source: google
family: Abel
files:
- https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6V1LPJp6qGI.woff2
urls:
- https://fonts.gstatic.com/s/abel/v18/MwQ5bhbm2POE6V1LPJp6qGI.woff2
format: woff2
```

The important new field is `format`. A resource can now say whether it provides
`ttf`, `otf`, `woff`, `woff2`, `ttc`, or `otc` files.

Each resource carries both a `files` list and a `urls` list. For Google Fonts
these are identical because each font file is downloaded directly by URL. For
archive-based formulas like Courier Prime, `urls` points to the downloadable
archive while `files` lists the font files extracted from within it.

The resource name is also more meaningful. Names such as `ttf_static`,
`woff2_static`, `ttf_variable`, and `woff2_variable` make it clear whether the
resource is a desktop font, web font, static font, or variable font resource.

## Styles know their available formats

Formula v5 also records format information on each style:

```yaml
fonts:
- name: Abel
styles:
- family_name: Abel
type: Regular
full_name: Abel Regular
post_script_name: Abel-Regular
font: MwQ5bhbm2POE6VhLPJp6qGI.ttf
formats:
- ttf
- woff2
variable_font: false
```

The `font` field is how a style connects to its resources: its value is a
filename that appears in one of the resource `files` lists. The `formats` array
then tells Fontist that the same style is available in other resources as well.
In the example above, the `font` field references a `.ttf` filename found in
the `ttf_static` resource, but the `formats` array also lists `woff2`,
indicating that a WOFF2 version is available through the `woff2_static`
resource.

This means Fontist can tell that "Abel Regular" is available in both TTF and
WOFF2. Users and tools can then request a format explicitly:

```sh
$ fontist install "Abel" --format woff2
```

When the user requests a specific format, Fontist first looks for a resource
that already provides it. If no exact match exists, Fontist checks whether
conversion from an available format is possible (for example, converting TTF to
WOFF2). An exact-match resource is always preferred over conversion.

## Variable font metadata

Variable fonts are one of the main reasons for Formula v5.

A variable font can contain a range of designs in a single font file. Instead
of installing separate files for Regular, Bold, Condensed, or other fixed
instances, a variable font exposes axes such as weight (`wght`), width (`wdth`),
slant (`slnt`), or optical size (`opsz`).

Formula v5 represents this with `variable_font` and `variable_axes`.

Roboto Flex is a good example. (The `HASH` placeholders below stand in for
the long hashed filenames that Google Fonts uses.)

```yaml
resources:
woff2_variable:
source: google
family: Roboto Flex
files:
- https://fonts.gstatic.com/s/robotoflex/v30/HASH.woff2
urls:
- https://fonts.gstatic.com/s/robotoflex/v30/HASH.woff2
format: woff2
variable_axes:
- GRAD
- XOPQ
- XTRA
- YOPQ
- YTAS
- YTDE
- YTFI
- YTLC
- YTUC
- opsz
- slnt
- wdth
- wght
ttf_variable:
source: google
family: Roboto Flex
files:
- https://fonts.gstatic.com/s/robotoflex/v30/HASH.ttf
urls:
- https://fonts.gstatic.com/s/robotoflex/v30/HASH.ttf
format: ttf
variable_axes:
- GRAD
- XOPQ
- XTRA
- YOPQ
- YTAS
- YTDE
- YTFI
- YTLC
- YTUC
- opsz
- slnt
- wdth
- wght
```

The same metadata is available on styles. Notice that `font` references a
`.ttf` filename from the `ttf_variable` resource, while `formats` declares that
WOFF2 is also available:

```yaml
fonts:
- name: Roboto Flex
styles:
- family_name: Roboto Flex
type: Regular
font: HASH.ttf # filename from ttf_variable resource
formats:
- ttf
- woff2
variable_font: true
variable_axes:
- GRAD
- XOPQ
- XTRA
- YOPQ
- YTAS
- YTDE
- YTFI
- YTLC
- YTUC
- opsz
- slnt
- wdth
- wght
```

The `variable_axes` array appears on both resources and styles. They serve
different purposes: on a resource, axes describe what the font file physically
contains. On a style, axes describe what is available to the user across all
resources for that style. Style-level axes are derived automatically during
import and migration, so they stay in sync with the underlying resources.

In practice the two lists are usually identical, but they can diverge when
resources for the same style offer different axis sets. When that happens and a
user requests specific axes, Fontist selects the resource that satisfies the
request.

This enables capability-based workflows:

```sh
$ fontist find --variable
$ fontist find --axes wght,wdth
$ fontist install "Roboto Flex" --variable-axes wght,wdth
$ fontist install "Roboto Flex" --prefer-variable
```

Fontist can now answer questions such as "which fonts support weight and width
axes?" and "install the variable version when one is available."

## Import provenance

Formula v5 can record where an imported formula came from.

The `import_source` field is typed by source. For macOS supplementary fonts, it
tracks the framework version, posting date, and asset ID:

```yaml
import_source:
type: macos
framework_version: 8
posted_date: '2025-08-05T18:58:57Z'
asset_id: 10m11177
```

Google and SIL formulas can carry source-specific metadata as well:

```yaml
import_source:
type: google
commit_id: abc123def456
api_version: v1
last_modified: '2026-04-01T00:00:00Z'
family_id: roboto-flex
```

```yaml
import_source:
type: sil
version: 6.200
release_date: '2024-02-01'
```

This improves auditing and update detection. Fontist can distinguish formulas
that came from different upstream sources and can compare source metadata when
checking whether an imported formula is outdated. For example:

```sh
$ fontist check-updates --source google
Outdated formulas:
roboto_flex: local commit abc123, upstream commit def456
abel: up to date
```

Without `import_source`, Fontist would have no way to tell whether a formula's
upstream has moved ahead.

## Structural comparison

| Aspect | Formula v4 | Formula v5 |
|---|---|---|
| Schema version | Implicit | Explicit `schema_version: 5` |
| Resource model | Usually one package or archive | Multiple resources by capability |
| Resource format | Inferred from files | Declared with `format` |
| Style format metadata | Not available | Declared with `formats` |
| Variable fonts | Not represented | `variable_font` and `variable_axes` |
| Capability search | Limited to formula/style names | Can filter by format, variable font support, and axes |
| Import provenance | Not represented | Typed `import_source` metadata |

Comment thread
HassanAkbar marked this conversation as resolved.
## What this enables

Formula v5 gives Fontist a richer view of each font family.

For desktop use, Fontist can still install TTF or OTF files as before. For web
projects, it can choose WOFF2 resources where they are available. For modern
typography workflows, it can find and install variable fonts by supported axes.

The new structure also helps formula maintainers. Imported formulas can record
their upstream source, and migrated formulas can preserve their existing
installation behavior while gaining an explicit schema version.

## Migration

The official Fontist formulas repository has been migrated to v5. The current
repository contains more than 4,000 formula files, including Google Fonts,
macOS supplementary fonts, SIL fonts, and manually-maintained formulas.

For formula maintainers, the recommended path depends on the source:

* Re-import generated formula sets such as Google Fonts, macOS fonts, and SIL
fonts with `--schema-version=5`.
* Use the migration command for custom or manually-maintained formulas.

```sh
$ fontist migrate-formulas ./Formulas ./output --dry-run
```

The migration keeps v4 compatibility in mind. A formula without
`schema_version` is still treated as v4, and existing custom formulas continue
to work.

## Conclusion

Formula v5 makes Fontist formulas explicit about the font capabilities they
describe.

Instead of assuming one resource and one desktop-oriented format, formulas can
now declare multiple formats, identify variable font resources, list supported
axes, and record where imported metadata came from.

That structure gives Fontist the foundation for better format selection,
variable font discovery, source auditing, and future schema evolution while
preserving compatibility with existing v4 formulas.
2 changes: 2 additions & 0 deletions lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ exclude = [
"/blog/2022-02-11-macos-fonts$",
"/blog/2024-01-23-office-fonts$",
"/blog/2024-03-02-creating-formulas$",
# Exclude placeholder URLs in code examples
"fonts\\.gstatic\\.com/s/robotoflex/v30/HASH",
]
Loading