Font Tooling Setup

Metal Type

Zach Leat's superb overview of his web-font loading process for CSS-Tricks is just a thing of beauty. He really delves into the details, providing a practical approach for front end devs and type nerds. Sophisticated command line font tools are featured heavily in his approach. This post will show you how to set them up on a Mac.

The cascade of commands described below will set up our machine with a python library called fonttools and pyftsubset which we can use to subset our webfonts, reducing file sizes for faster browser performance.

All the commands below are run in the command line shell.


Homebrew is the "missing package manager for macOS (or Linux)", it's basically like npm to node or bundler/rubygems to ruby. We'll need this to install python, which we'll need to install fonttools.

You might need xcode installed if you haven't already installed it. Run the below command and be prepared to wait. See this homebrew discourse thread for potential troubleshooting.

xcode-select --install

Now, let's install Homebrew.

/usr/bin/ruby -e "$(curl -fsSL"

For a sanity check in case you missed any errors that flew by, run brew doctor for troubleshooting assistance.

brew doctor


Great! With Homebrew all set up, let's use it to install Python. We are going to need v3.0 or greater for fonttools to work. Mac's do come pre-installed with Python, let's see which version it is

python --version

To get v3, run

brew install python3

Homebrew is super helpful, suggesting you link python

brew link python3

If you could not get python working or see an error message, it could be about usr/local permissions. Mac Sierra made directory permission changes that Homebrew will need access to. See this stackoverflow post to fix.

Lastly, you might run the python command and not see v3.7. Homebrew has a page on this issue. Run python3 to use v3.7 when running commands in python.

python3 run command here

Finally, you'll need pip, the python package manager. It should be installed when you did brew install python3. But if you have a different python version or installed it a different way, there are several ways to get pip installed, one deprecated and one that is the new offical suggestion.

Here is the official installation commands.

curl -o

Let's run the python shell to see if everything works.


And quit() to exit.


Font Tools

We are ready to install fonttools. You can use pip or homebrew.

pip install fonttools


brew install fonttools

We will need brotli for woff2 compression when running the pyftsubset command.

pip install brotli

We did it, now we can use the amazing pyftsubset command. I haven't found much documentation online for this tool, but the --help flag is super in-depth. There are many options for pyftsubset and the commands get pretty long. When looking at the list of options, it truly is astounding how much technical detail goes into creating web fonts. There is a lot going on behind the scenes!

pyftsubset --help
pyftsubset "PublicSans.ttf" --output-file="PublicSans.woff2" --flavor=woff2 --layout-features="*" --no-hinting --desubroutinize --unicodes=U+0-10FFFF

--flavor=woff2 will create a woff2 compressed file for our font.

--layout-features="*" will include all OpenType features. This is a whole other avenue I haven't explored. The command below will list all features if you want to learn more.

pyftsubset "PublicSans-Medium.ttf" --layout-features="?"

--no-hinting will not include hinting features in the OpenType file. Hinting is the process of optimizing the font for maximum screen readability.

--unicodes=U+0-10FFFF will include our range of glyphs we need for our website.


Glyphhanger is built on top of fonttools and has awesome web font powers built in. Font expert Zach Leat has much to say about it here. You can get it with npm

npm install -g glyphhanger

Some noticeable differences between pyftsubset and glyphhanger are: glyphhanger crawls websites, returns the unicode characters and outputs a woff/woff2 subsetted web font, super powerful stuff!

But glyphhanger is missing the --layout-features flag and several others that make pyftsubset a precise tool for cutting out font features depending on your needs. It really shines by returning a list of unicode characters on a site which you can use for subsetting to reduce web font sizes.


Combine these two together and you have an efficient subsetting and compression approach for delivering web fonts.

This article covers subsetting a webpage with glyphhanger and this one too.