Library / SDK
fonttools/fonttools avatar
fonttools/fonttools

fonttools: reading, subsetting and converting fonts from Python

A library to manipulate font files from Python.

5,272 stars545 forksPythonMIT

At a glance

What is it?
fontTools is an MIT-licensed Python library for manipulating TrueType, OpenType, AFM and, to a degree, Type 1 fonts, and it ships the TTX converter. It is a scripting toolkit, not a font editor, and the optional extras decide which features actually work.
Who is it for?
Adopt fontTools when you need scripted, repeatable font processing: subsetting, table inspection, TTX round-trips, or building font steps into a Python pipeline. Do not adopt it as a drawing application; the README does not describe a GUI, and the project is a library plus command-line tools.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Python, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 2, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What fontTools solves, and who ends up using it

Font files are binary containers. A single OpenType font holds a glyph outline table, a character-to-glyph map, kerning, layout rules and name records, each with its own binary layout. Editing one by hand is not practical, and most drawing applications do not expose the tables at all. fontTools addresses that gap: the README describes it as "a library for manipulating fonts, written in Python", and it supports TrueType, OpenType, AFM and, to an extent, Type 1 plus some Mac-specific formats.

The audience is narrower than the topic suggests. This is for people who already write Python and need font work inside a script: a build step that strips a web font down to a character set, a check that a generated font has the tables you expect, a batch conversion of a directory of files. Font designers can use it, but through the TTX route rather than by drawing. Anyone looking for a canvas, a pen tool and a preview pane is looking at the wrong project, and the README does not present one.

TTX and the table model behind the command line tools

The core idea is that a binary font can be taken apart into named tables and written back out. The README states that the project includes the TTX tool, which converts TrueType and OpenType fonts to and from an XML text format also called TTX. That round trip is the mechanism everything else sits on: dump a font to XML, read or modify the XML, compile it back into a binary font.

Around that, the repository is organised as a package under Lib/fontTools, with subpackages for the table library (ttLib), variable font work (varLib), UFO sources (ufoLib) and assorted helpers under misc. Optional behaviour is not hidden behind runtime flags but behind importable dependencies. The README lists them module by module: Lib/fontTools/ttLib/woff2.py needs brotli for WOFF 2.0 compression, Lib/fontTools/misc/etree.py prefers lxml when present, Lib/fontTools/varLib/interpolatable.py needs scipy or munkres to solve the assignment problem for matching contours between masters, and Lib/fontTools/ttLib/removeOverlaps.py needs skia-pathops. If the dependency is missing, the feature is unavailable. That is a deliberate design: the base package has no required external dependencies beyond the Python Standard Library.

Installing fontTools with pip and running a first TTX dump

fontTools requires Python 3.11 or later according to the README, and the package is on PyPI. The documented install is a single pip command:

bash
pip install fonttools

Optional features come from extras, and the README gives this exact example:

bash
pip install fonttools[ufo,lxml,woff,unicode]

That installs the optional dependencies for the ufo, lxml, woff and unicode groups. If you plan to work with WOFF 2.0 web fonts, the woff extra is what pulls in brotli; without it, that module cannot run.

For contributors, the README recommends a virtual environment and an editable install:

bash
git clone https://github.com/fonttools/fonttools.git
cd fonttools
python -m virtualenv fonttools-venv
. fonttools-venv/bin/activate
pip install -e .

On Windows cmd.exe the activation step is fonttools-venv\Scripts\activate.bat instead. Once installed, the TTX tool is what you reach for first: it converts a TrueType or OpenType font to the XML text format described in the README, and converts it back. The README does not print a worked command line for it, so check the installed entry points and the user documentation at fonttools.readthedocs.io before scripting against a specific invocation.

Subsetting and the extras you must install first

The search traffic around this project clusters on two entry points: ttx and pyftsubset. Subsetting is the operation most production users want, because shipping a full font to a web page that uses forty glyphs wastes bandwidth. The subsetting code lives in the package, and the README's optional requirements section is where you find out what has to be installed for the surrounding features.

The practical trap is the extras. The README is explicit that some modules need packages the base install does not bring in, and it names the extra for each: lxml for the ElementTree-like API in Lib/fontTools/misc/etree.py, woff for WOFF 2.0 via brotli and for the zopfli path in Lib/fontTools/ttLib/sfnt.py, unicode for unicodedata2 so that dumping the cmap table shows current Unicode character names, interpolatable for contour matching, plot for DesignSpaceDocument visualisation, symfont for symbolic font statistics, type1 for Macintosh PostScript Type 1 creator and type metadata, pathops for removeOverlaps, and ufo for UFO reading and writing. The README notes that lxml is "preferred whenever present, as it is generally faster and more secure" than the built-in xml.etree. That is a real decision point: install lxml if you are parsing untrusted fonts at volume, and skip it if you want the smallest possible dependency set.

A second constraint is version drift in the Unicode data. The README points out that the unicodedata module in the Standard Library varies between Python versions, and offers unicodedata2, described there as a backport "updated to the latest Unicode version 18.0", as the way to get consistent character names. If your output includes cmap dumps, that difference shows up in the text.

Where fontTools is the wrong tool

The most common mismatch is expecting an editor. fontTools is a library with command-line front ends. There is no document model, no undo, no live preview. If your task is drawing a curve and nudging it until it looks right, this is the wrong layer, and the README makes no claim otherwise.

The second limitation is dependency weight for the advanced paths. The base package is deliberately dependency-free, but the features that need solving or geometry pull in heavy packages. Contour matching between masters needs scipy or munkres; the README notes scipy is "very fast" because it uses NumPy arrays while munkres is a pure-Python implementation of the Hungarian algorithm, "slower than SciPy, but useful for minimalistic systems where adding SciPy is undesirable". Plotting results to PDF or HTML additionally needs pycairo, and the README warns that pycairo wheels are currently available only for Windows, with other platforms directed to pycairo's own installation instructions. So the visualisation path is not a clean pip install everywhere.

Third, coverage is not uniform across formats. The README says Type 1 support is partial ("to an extent") and that some Mac-specific formats are supported, which is not the same as full support. If your pipeline is built on Type 1, verify against your own files rather than assuming parity with the TrueType and OpenType paths. And if you need a format the README never lists, the documentation is silent on it.

How it compares with a font editor and with fontmake

The obvious alternative is a graphical font editor. The difference is not quality but layer: an editor gives you a canvas, interactive spacing and a preview, and it is the right tool for designing letterforms. fontTools gives you a Python API and a text representation of the binary tables, and it is the right tool for automating what an editor would otherwise require a human to click through. They overlap only in that both can open the same font file.

The closer alternative for source-to-binary work is fontmake, which is itself built on fontTools and on ufo2ft. The README's requirements.txt lists ufo2ft and ufoLib2 among the packages used to run parts of the test suite, which tells you the relationship: fontmake orchestrates a compile pipeline from UFO sources, while fontTools supplies the table-level machinery underneath. If your goal is "take this designspace and produce a variable font", reach for the build tool. If your goal is "inspect, subset, patch or convert this binary font", fontTools is the layer you want. Choosing the wrong one means either reimplementing a build pipeline or fighting an abstraction that was never meant to be a build system.

Maintenance, releases and the MIT licence

The repository is not archived, and the last push was on 2026-09-18, so the project is being worked on. Releases are frequent and small: 4.65.0 on 2026-09-10, 4.64.0 on 2026-08-31, and 4.63.0 on 2026-05-14. That cadence matters for upgrade cost. Changes arrive per release, and the repository carries a NEWS.rst changelog at the top level, so the practical upgrade routine is to read the entry for the version you are moving to and pin an exact version in your requirements rather than tracking the newest one.

Python version support is another recurring cost. The README states fontTools requires Python 3.11 or later and that the maintainers try to support the Python versions still supported upstream. That means dropping an older interpreter is a normal event, not an exception, and a pinned environment will eventually block you.

The licence is MIT. The README says the project has an MIT open-source licence and that "you can use it free of charge". Note that the repository also contains a LICENSE.external file alongside LICENSE, and the README lists optional dependencies with their own licences (lxml, scipy, pycairo, skia-pathops and the rest). If you redistribute a bundle that includes those extras, their terms apply separately. That is a packaging question for your own legal review, not something this article can settle.

Editorial conclusion

Adopt fontTools when you need scripted, repeatable font processing: subsetting, table inspection, TTX round-trips, or building font steps into a Python pipeline. Do not adopt it as a drawing application; the README does not describe a GUI, and the project is a library plus command-line tools. Before committing, verify that your Python is 3.11 or later, install the extras for the features you actually call (woff for WOFF 2.0, lxml for the faster XML backend, pathops for removeOverlaps, ufo for UFO sources), and check the NEWS.rst entry for the version you pin, since features arrive per release rather than in one documented freeze.

Frequently asked questions

How do I install fontTools?

Install it from PyPI with pip install fonttools. The README states the package requires Python 3.11 or later, and that optional features need extras such as fonttools[ufo,lxml,woff,unicode].

How do I use fontTools from Python?

The README describes fontTools as a Python library for manipulating fonts, with user and developer documentation hosted on Read the Docs. It also ships the TTX tool, which converts TrueType and OpenType fonts to and from an XML text format.

How do I use fontTools?

The two documented entry points are the TTX tool for converting fonts to and from XML, and the library itself for scripted table work. The README points to fonttools.readthedocs.io for user documentation.

Official sources

  1. fonttools/fonttools on GitHub
  2. Issues
  3. License: MIT
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/fonttools-fonttools.svg)](https://hysenlabs.com/projects/fonttools-fonttools)