Privacy-respecting, self-hostable variable web fonts — a small Google Fonts alternative.
This repo builds tiny, subsetted variable woff2 files and serves them from a
Cloudflare Worker at https://fonts.grunt.si with long-lived immutable caching
and permissive CORS. No tracking, no cookies, no request logging.
Two ways to use a font:
- Link the CDN —
@font-facestraight tofonts.grunt.si(one shared copy, zero build step). - Self-host — copy the
woff2into your ownstatic/fonts/for a same-origin request (fastest, no third-party dependency).
The repo is the single source of truth for how each font is subset (the build
scripts) and the generated asset itself (fonts/*.woff2).
| Family | File | Axis | Coverage | Licence |
|---|---|---|---|---|
| Ubuntu Sans Variable | ubuntu-sans-v4-latin.woff2 (~65 KB) |
wght 200–700 |
Latin + Latin Extended (EU incl. sl/de) | UFL 1.0 |
| Quicksand | quicksand-v-latin.woff2 (~40 KB) |
wght 300–700 |
Latin + Latin Extended | OFL 1.1 |
Each font is a single variable file (the whole weight range in one request), width axis instanced to 100, and subsetted to Latin + Latin Extended (dropping Cyrillic/Greek). Slovenian, German, and most EU diacritics are covered.
@font-face {
font-family: 'Ubuntu Sans Variable';
font-style: normal;
font-display: swap;
font-weight: 200 700;
src: url('https://fonts.grunt.si/fonts/ubuntu-sans-v4-latin.woff2') format('woff2-variations');
}
@font-face {
font-family: 'Quicksand';
font-style: normal;
font-display: swap;
font-weight: 300 700;
src: url('https://fonts.grunt.si/fonts/quicksand-v-latin.woff2') format('woff2-variations');
}Preload for best LCP:
<link rel="preload" href="https://fonts.grunt.si/fonts/ubuntu-sans-v4-latin.woff2" as="font" type="font/woff2" crossorigin />Visit https://fonts.grunt.si for live copy-paste snippets.
Copy the woff2 (+ its licence file) from fonts/ into your project's
static/fonts/ and point @font-face at the local path instead. Keep the
licence file alongside the font (UFL/OFL require it for redistribution).
Requires python3 (creates a venv with fonttools[woff] + brotli).
bun run fonts:all # build both
bun run fonts:ubuntu # just Ubuntu Sans
bun run fonts:quicksand # just QuicksandEach script downloads the canonical upstream variable font, instances the width
axis, clamps the weight axis to the range we ship, subsets to Latin + Latin
Extended, and writes a woff2 + the upstream licence into fonts/.
- Copy
scripts/build-font-quicksand.sh→scripts/build-font-<name>.sh. - Point it at the upstream variable TTF + its licence, set the
wghtrange + unicode subset. - Add the face to
FONT_FACESinsrc/index.ts(so the index page + snippets pick it up). - Add an
fonts:<name>script + include it infonts:allinpackage.json. bun run fonts:<name>and commit the generatedwoff2+ licence.
CI deploys to fonts.grunt.si on push to main. Manual:
bun run deploy # runs sync-public (copies fonts/ → public/fonts/) then wrangler deployfonts/— committed source-of-truth woff2s + their licences.public/_headers— immutable cache + CORS for/fonts/*(served straight from the edge).src/index.ts— Worker that renders the index page at/; font assets serve directly.wrangler.jsonc—run_worker_first: ["/", "!/fonts/*"]so only the index hits the Worker.
Build scripts + Worker code: MIT (see LICENSE). The fonts are
redistributed under their own licences (UFL / OFL), preserved in fonts/.