-
Notifications
You must be signed in to change notification settings - Fork 1
Added blog post for v5 formulas #31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
HassanAkbar
wants to merge
3
commits into
main
Choose a base branch
from
blog-post-for-v5-formulas
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | | ||
|
|
||
| ## 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. | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.