Using the woff2 format and font subsetting (eg. via glyphhanger) you can get small font files for hosting web fonts yourself.
Lately I’ve found a beautiful mono-spaced font called Iosevka (I like the etoile variant best). For coding I still prefer Cascadia Code but for normal reading I do refer it over cascadia code.
If you actually download the font, you’ll find that the release zip file is ~120MB (or in the ballpark, depending on version), a single ttf file is around ~10MB and even the woff2 version (which is a format already compressed and optimized for usage on the web) is ~2MB in size.
As a custom font is hardly a necessary feature of any webpage and at best a nice-to-have, 2MB is waaay to big for a vanity download.
Considering that in my use case I would probably only need ~60+ chars (10 digits + 26 letters + 26 more in uppercase and a couple of special characters) I wanted a smaller file that only contains the characters that I am using.
Turns out that the process of creating a smaller font from a subset of codepoints is called font subsetting (duh!) and there are a couple of nice tools like glyphhanger, which can do that for you if you give them a website to crawl or a list of the characters required.
So I threw together a short Dockerfile that sets up glyphhanger with woff2 export support and a script to instruct it to generate a woff2 subset with the whitelisted characters here.
The docker file installs glyphhanger via bun and the prerequisites for the enabling the woff2 export:
FROM oven/bun:alpine
RUN apk add python3 py3-pip py3-fonttools py3-brotli py3-zopfli
RUN bun i -g glyphhanger
ENTRYPOINT [ "glyphhanger" ]
The following script volume maps the current directory (which should contain the input ttf files) into the container and instructrs glyphhanger to create a font subset in woff2 format:
docker run -v $(pwd):/home/bun/app glyphhanger --whitelist="/.- 0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ" --subset=*.ttf --formats=woff2
Running that with my favourite font files, I get the following output files that are ~69KB in size:
-rw-r--r-- 1 9.6M Iosevka-Regular.ttf
-rw-r--r-- 1 68K Iosevka-Regular-subset.woff2
-rw-r--r-- 1 9.6M IosevkaEtoile-Regular.ttf
-rw-r--r-- 1 69K IosevkaEtoile-Regular-subset.woff2
Which I find adequate in size for some eye candy.