Skip to content

grunt-it/fonts

Repository files navigation

grunt fonts

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:

  1. Link the CDN@font-face straight to fonts.grunt.si (one shared copy, zero build step).
  2. Self-host — copy the woff2 into your own static/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).


Available fonts

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.

Use it — link the CDN

@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.

Use it — self-host

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).

Rebuild the fonts

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 Quicksand

Each 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/.

Add a new face

  1. Copy scripts/build-font-quicksand.shscripts/build-font-<name>.sh.
  2. Point it at the upstream variable TTF + its licence, set the wght range + unicode subset.
  3. Add the face to FONT_FACES in src/index.ts (so the index page + snippets pick it up).
  4. Add an fonts:<name> script + include it in fonts:all in package.json.
  5. bun run fonts:<name> and commit the generated woff2 + licence.

Deploy

CI deploys to fonts.grunt.si on push to main. Manual:

bun run deploy   # runs sync-public (copies fonts/ → public/fonts/) then wrangler deploy

How it works

  • fonts/ — 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.jsoncrun_worker_first: ["/", "!/fonts/*"] so only the index hits the Worker.

Licence

Build scripts + Worker code: MIT (see LICENSE). The fonts are redistributed under their own licences (UFL / OFL), preserved in fonts/.

About

Privacy-respecting, self-hostable variable web fonts (Ubuntu Sans + Quicksand) served from fonts.grunt.si — a small Google Fonts alternative.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors