Picture of fontite

fontite

Published February 3, 2022

I've spent a lot of time optimizing my website to make sure it loads fast and respects user privacy while still being functional and looking nice. I think tasteful use of icons as visual cues can make a big difference in how a site looks, so I started using Font Awesome pretty early on.

For a while, I was directly requesting icon font CSS directly from Font Awesome, and using classes like fas fa-* in my HTML. There's a number of issues with that approach though! I was able to fix some of them, like privacy, security, and content-availability guarantees, by simply downloading the relevant files to my own server and including them as first-party resources.

Still, a few big issues remained...

extensibility

It's ultimately up to the Font Awesome developers' discretion which icons make it into their font and which don't. At one point I added a link to connect with my Matrix chat server, but there's no Matrix icon in Font Awesome's library! There is an open issue with a good number of +1s, but that doesn't help me if it never gets accepted.

My interim solution was to serve a separate SVG file, but this got clunky fast. Suddenly I needed two different but equivalent ways of displaying an icon in HTML. I had to pay very careful attention to scaling behavior, and had to make manual edits when I realized that you can't really recolor an SVG icon like you can with the color CSS property for fonts. That was only compounded when I decided I also wanted a different color on hover!

resource size

My website is made of carefully hand-crafted HTML and CSS. While it's great that I was able to add these icons to my pages without any JavaScript, eventually I realized that the CSS and font files I'd been forcing visitors to request were an order of magnitude larger than everything else on my website combined! This was causing a visible flash as the icons appeared later than the rest of the content on uncached page loads.

I had no use for 99% of the icons being downloaded, so why force them all on visitors?

simplicity

Of course, this isn't an unsolved problem. The obvious thing to do is pack only the necessary icons together into a single font.

After some research, I found out about a handful of existing icon font optimization tools - Fontello, IcoMoon, Fontastic, icnfnt. Unfortunately, half of these are proprietary projects on someone else's servers, the other half have large, complex codebases... and all of them are designed to be used in a browser.

I just want a simple CLI tool with a simple configuration format. Something I can edit with my existing text editor, check-in to my existing version control system, and then run without supervision in my existing build automation.

a better way

FontForge happens to have all the font transformation tools I need, along with a corresponding Python scripting API for each of them.

Thus, fontite was born. It's a simple layer around the FontForge API that generates optimized icon fonts from a TOML configuration file designed to be edited by humans.

It supports combining icons from as many different input font sources and SVGs as you could possibly want. It only requires Python, Tomli, and FontForge. And it executes faster than you can blink.

I use it to generate the icon fonts for this website. I've also created a demo page with some size benchmarks and a full configuration example.

Let's build some smaller, faster websites!