Font Version Control: Managing Font Versions with Git
Learn how to track font changes, manage releases, and automate builds using Git, semantic versioning, and CI/CD pipelines for font projects
In Simple Terms
Use text-based source formats (UFO, Glyphs, Designspace) in Git for meaningful diffs. Binary fonts (TTF, OTF, WOFF2) should be build artifacts, not tracked sources. Store binaries with Git LFS if needed.Follow OpenType versioning: Major.Minor format in the font's name table (e.g., Version 2.3). Map this to semver tags (v2.3.0) in Git. Use tools like font-v to automate version bumping.Automate font compilation with GitHub Actions or similar CI. Run FontBakery quality checks on every push, and produce WOFF2 web fonts as build artifacts from source files.
In this article
Why Version Control for Fonts?
Font files are software. Like any software, they evolve over time -- new characters are added, kerning is refined, bugs are fixed. Without version control, font projects suffer from the same problems as unversioned code: lost changes, unclear history, and collaboration conflicts.
| Without Version Control | With Version Control |
|---|---|
| MyFont-v2-final-FINAL-v3.otf | git log shows complete history with meaningful messages |
| No way to see what changed between versions | git diff shows exactly which glyphs or metrics changed |
| Emailing font files between collaborators | Branches and pull requests for collaborative editing |
| Manual export to web formats | CI/CD automatically builds WOFF2, runs quality checks |
Google Fonts -- which manages over 1,050 font families -- requires all submissions to be maintained in public Git repositories with automated CI builds. This practice, pioneered by the open-source font community, has become the standard for professional font development. GitHub Actions automates build + FontBakery checks in approximately 2 minutes per build.
Source Formats for Version Control
The key to effective font version control is using text-based source formats that Git can diff meaningfully. Binary formats (TTF, OTF) change completely with every edit, making diffs useless.
| Format | Type | Git-Friendly? | Used By |
|---|---|---|---|
| UFO (.ufo) | XML directory (text) | Excellent | RoboFont, FontForge, fontmake |
| Glyphs (.glyphs) | Text plist | Good | Glyphs.app |
| Glyphs 3 (.glyphx) | Package directory | Excellent | Glyphs 3 |
| Designspace (.designspace) | XML (text) | Excellent | Variable font projects |
| FontLab (.vfj) | JSON (text) | Good | FontLab 8 |
| TTF/OTF | Binary | Poor | Build artifacts only |
Pro Tip
UFO (Unified Font Object) is the most Git-friendly format because each glyph is stored as a separate XML file. When you modify one character, only that file changes in the commit, making code review straightforward. Note: Glyphs 3 now supports .glyphspackage format (a directory bundle) which is similarly Git-friendly, and FontLab 8.3+ can open it natively.
Git Repository Setup
A well-structured font repository separates source files from build outputs and includes proper ignore rules.
# Recommended repository structure
my-font-family/
├── sources/
│ ├── MyFont-Regular.ufo/
│ ├── MyFont-Bold.ufo/
│ └── MyFont.designspace
├── fonts/
│ ├── ttf/ # Built TTF files
│ ├── otf/ # Built OTF files
│ └── webfonts/ # Built WOFF2 files
├── scripts/
│ └── build.py # Font build script
├── .gitignore
├── .gitattributes
├── LICENSE.txt # OFL or commercial license
├── METADATA.pb # Google Fonts metadata (if applicable)
└── README.md.gitignore for Font Projects
# Build outputs (regenerated from sources)
fonts/ttf/
fonts/otf/
fonts/webfonts/
# OS files
.DS_Store
Thumbs.db
# Editor backups
*.bak
*~
# Python build cache
__pycache__/
*.pyc
build/
dist/
*.egg-info/.gitattributes for Font Projects
# Treat font source files as text for proper diffing
*.ufo/** text
*.glyphs text
*.designspace text
*.fea text
# Binary font files (if tracked) use LFS
*.ttf filter=lfs diff=lfs merge=lfs -text
*.otf filter=lfs diff=lfs merge=lfs -text
*.woff filter=lfs diff=lfs merge=lfs -text
*.woff2 filter=lfs diff=lfs merge=lfs -textFont Versioning Conventions
OpenType fonts store a version number in the name table (nameID 5) as "Version X.YYY". This is separate from your Git tags but should be kept in sync.
| Version Change | When to Use | Example |
|---|---|---|
| Major (X.0) | Breaking changes: major redesign, glyph redraws, metric changes | Version 2.000 (redesigned lowercase) |
| Minor (X.Y) | New features: added glyphs, new OpenType features, new weights | Version 2.100 (added Cyrillic support) |
| Patch (X.YZZ) | Bug fixes: kerning corrections, hinting fixes, metadata updates | Version 2.101 (fixed AV kerning pair) |
# Using font-v to manage font versions
pip install font-v
# Check current version
font-v report MyFont-Regular.ttf
# Bump version (updates name table + head table)
font-v write --ver=2.100 MyFont-Regular.ttf
# Tag the Git release to match
git tag -a v2.100 -m "Version 2.100: Added Cyrillic support"
git push origin v2.100Branching & Collaboration Workflows
Solo Font Developer
For individual type designers, a simple trunk-based workflow works well:
- Work on
mainbranch for day-to-day development - Create feature branches for major additions (e.g.,
feature/cyrillic-support) - Tag releases with version numbers (
v2.100) - Commit frequently with descriptive messages
Team Font Development
For multi-designer teams, use a pull request workflow:
mainis always release-ready (protected branch)- Feature branches for each designer's work (e.g.,
alice/italic-refinements) - Pull requests require review from at least one other designer
- CI runs FontBakery checks before merge is allowed
- Release branches for final QA before tagging
Pro Tip
When multiple designers work on the same font, assign glyph ranges to avoid merge conflicts. Designer A works on uppercase A-M while Designer B works on N-Z. UFO format makes this practical since each glyph is a separate file.
CI/CD Font Build Automation
Automate font compilation with CI/CD so every commit produces tested, production-ready font files. This is the standard workflow for Google Fonts and most open-source font projects.
# .github/workflows/build-fonts.yml
name: Build Fonts
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: pip install fontmake fonttools[woff] fontbakery # FontBakery 1.1.0+
- name: Build fonts from UFO sources
run: |
fontmake -m sources/MyFont.designspace \
-o ttf --output-dir fonts/ttf/
fontmake -m sources/MyFont.designspace \
-o variable --output-dir fonts/variable/
- name: Generate WOFF2 web fonts
run: |
for ttf in fonts/ttf/*.ttf; do
fonttools ttLib.woff2 compress "$ttf" \
-o "fonts/webfonts/$(basename ${ttf%.ttf}.woff2)"
done
- name: Run FontBakery quality checks
run: |
fontbakery check-universal fonts/ttf/*.ttf \
--checkid !com.google.fonts/check/name/trailing_spaces \
-l WARN
- name: Upload build artifacts
uses: actions/upload-artifact@v4
with:
name: font-files
path: |
fonts/ttf/
fonts/variable/
fonts/webfonts/Git LFS for Binary Font Files
If you need to track compiled font binaries in Git (for distribution repos or when build automation is not available), use Git Large File Storage (LFS) to avoid bloating your repository.
# Install and set up Git LFS
git lfs install
# Track binary font formats with LFS
git lfs track "*.ttf"
git lfs track "*.otf"
git lfs track "*.woff"
git lfs track "*.woff2"
# Commit the .gitattributes file
git add .gitattributes
git commit -m "Configure Git LFS for binary font files"
# Now add and commit font files as normal
git add fonts/
git commit -m "Add compiled font binaries v2.100"Warning
GitHub Free accounts include 1GB of LFS storage and 1GB/month bandwidth. For font projects with many weights and frequent releases, this can be exhausted quickly. Consider GitHub Pro ($4/month for 2GB) or storing binaries as GitHub Release assets instead of LFS-tracked files.
Best Practices
Commit Sources, Build Binaries
Never commit TTF/OTF/WOFF2 as your source of truth. Commit UFO/Glyphs sources and let CI build the binaries. This keeps your repo diffable and history clean.
Write Good Commit Messages
Be specific: "Fix kerning for AV pair in Regular" is better than "Updated font". Include which glyphs or tables were modified.
Tag Every Release
Use annotated Git tags matching the font version number. This creates a clear release history and allows rollback to any version.
Include a LICENSE File
Every font repo should have a LICENSE.txt at the root. For open-source, use the SIL OFL. For commercial fonts, include a note referencing your license agreement. See our Font Licensing guide.
Next Steps
If you are building a font from scratch, see our Custom Font Creation guide for the design workflow. For enterprise teams managing many font projects, the Enterprise Font Management guide covers governance and scaling.
Written & Verified by
Sarah Mitchell
Product Designer, Font Specialist
Font Version Control FAQs
Common questions about managing font versions
