From 12c6f50e5d5cfd1f32878e8a8e7ba241b56747fc Mon Sep 17 00:00:00 2001 From: HassanAkbar Date: Tue, 14 Apr 2026 13:58:09 +0500 Subject: [PATCH 1/4] add blog post for v5 formulas --- blog/2026-04-14-formula-v5.md | 367 ++++++++++++++++++++++++++++++++++ 1 file changed, 367 insertions(+) create mode 100644 blog/2026-04-14-formula-v5.md diff --git a/blog/2026-04-14-formula-v5.md b/blog/2026-04-14-formula-v5.md new file mode 100644 index 0000000..f118641 --- /dev/null +++ b/blog/2026-04-14-formula-v5.md @@ -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 + + + +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: http://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 `NaN...` filenames below are real Google +Fonts hashed filenames, truncated here for readability.) + +```yaml +resources: + woff2_variable: + source: google + family: Roboto Flex + files: + - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.woff2 + urls: + - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.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/NaN...CKMY.ttf + urls: + - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.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: NaN...CKMY.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 | + +## 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. From 66bd70a506141b59c8d03b4b56d9acd7b5802683 Mon Sep 17 00:00:00 2001 From: HassanAkbar Date: Tue, 14 Apr 2026 14:54:23 +0500 Subject: [PATCH 2/4] fix link checker ci --- blog/2026-04-14-formula-v5.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/blog/2026-04-14-formula-v5.md b/blog/2026-04-14-formula-v5.md index f118641..68f1943 100644 --- a/blog/2026-04-14-formula-v5.md +++ b/blog/2026-04-14-formula-v5.md @@ -157,8 +157,8 @@ slant (`slnt`), or optical size (`opsz`). Formula v5 represents this with `variable_font` and `variable_axes`. -Roboto Flex is a good example. (The `NaN...` filenames below are real Google -Fonts hashed filenames, truncated here for readability.) +Roboto Flex is a good example. (The `` placeholders below stand in for +the long hashed filenames that Google Fonts uses.) ```yaml resources: @@ -166,9 +166,9 @@ resources: source: google family: Roboto Flex files: - - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.woff2 + - fonts.gstatic.com/s/robotoflex/v30/.woff2 urls: - - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.woff2 + - fonts.gstatic.com/s/robotoflex/v30/.woff2 format: woff2 variable_axes: - GRAD @@ -188,9 +188,9 @@ resources: source: google family: Roboto Flex files: - - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.ttf + - fonts.gstatic.com/s/robotoflex/v30/.ttf urls: - - https://fonts.gstatic.com/s/robotoflex/v30/NaN...CKMY.ttf + - fonts.gstatic.com/s/robotoflex/v30/.ttf format: ttf variable_axes: - GRAD @@ -218,7 +218,7 @@ fonts: styles: - family_name: Roboto Flex type: Regular - font: NaN...CKMY.ttf # filename from ttf_variable resource + font: .ttf # filename from ttf_variable resource formats: - ttf - woff2 From 410c3931988517ab996f6c63b90a085191315f1a Mon Sep 17 00:00:00 2001 From: HassanAkbar Date: Wed, 15 Apr 2026 11:46:39 +0500 Subject: [PATCH 3/4] resolve copilot comments --- blog/2026-04-14-formula-v5.md | 14 +++++++------- lychee.toml | 2 ++ 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/blog/2026-04-14-formula-v5.md b/blog/2026-04-14-formula-v5.md index 68f1943..f88d17e 100644 --- a/blog/2026-04-14-formula-v5.md +++ b/blog/2026-04-14-formula-v5.md @@ -45,7 +45,7 @@ Formula v4 did not declare its schema version. Formula v5 does: schema_version: 5 name: Courier Prime description: Courier Prime -homepage: http://quoteunquoteapps.com +homepage: https://quoteunquoteapps.com ``` If `schema_version` is missing, Fontist continues to treat the formula as a v4 @@ -157,7 +157,7 @@ slant (`slnt`), or optical size (`opsz`). Formula v5 represents this with `variable_font` and `variable_axes`. -Roboto Flex is a good example. (The `` placeholders below stand in for +Roboto Flex is a good example. (The `HASH` placeholders below stand in for the long hashed filenames that Google Fonts uses.) ```yaml @@ -166,9 +166,9 @@ resources: source: google family: Roboto Flex files: - - fonts.gstatic.com/s/robotoflex/v30/.woff2 + - https://fonts.gstatic.com/s/robotoflex/v30/HASH.woff2 urls: - - fonts.gstatic.com/s/robotoflex/v30/.woff2 + - https://fonts.gstatic.com/s/robotoflex/v30/HASH.woff2 format: woff2 variable_axes: - GRAD @@ -188,9 +188,9 @@ resources: source: google family: Roboto Flex files: - - fonts.gstatic.com/s/robotoflex/v30/.ttf + - https://fonts.gstatic.com/s/robotoflex/v30/HASH.ttf urls: - - fonts.gstatic.com/s/robotoflex/v30/.ttf + - https://fonts.gstatic.com/s/robotoflex/v30/HASH.ttf format: ttf variable_axes: - GRAD @@ -218,7 +218,7 @@ fonts: styles: - family_name: Roboto Flex type: Regular - font: .ttf # filename from ttf_variable resource + font: HASH.ttf # filename from ttf_variable resource formats: - ttf - woff2 diff --git a/lychee.toml b/lychee.toml index 56a4100..96b2863 100644 --- a/lychee.toml +++ b/lychee.toml @@ -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", ] From b7799ba01b44724ecc73ac47fe3a9e84ab318876 Mon Sep 17 00:00:00 2001 From: Ronald Tse Date: Sun, 3 May 2026 15:06:36 +0800 Subject: [PATCH 4/4] blog: add Windows FOD import source to formula v5 post --- blog/2026-04-14-formula-v5.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/blog/2026-04-14-formula-v5.md b/blog/2026-04-14-formula-v5.md index f88d17e..079732d 100644 --- a/blog/2026-04-14-formula-v5.md +++ b/blog/2026-04-14-formula-v5.md @@ -295,6 +295,16 @@ import_source: release_date: '2024-02-01' ``` +Windows Features on Demand (FOD) formulas track the Windows capability name and +minimum version: + +```yaml +import_source: + type: windows + capability_name: Language.Fonts.Jpan~~~und-JPAN~0.0.1.0 + min_windows_version: "10.0" +``` + 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: @@ -337,7 +347,8 @@ installation behavior while gaining an explicit schema version. 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. +macOS supplementary fonts, Windows FOD fonts, SIL fonts, and +manually-maintained formulas. For formula maintainers, the recommended path depends on the source: