Font Downloader
A CLI to find and download Google Fonts. It consolidates TTF/OTF/TTC from the family ZIP or the google/fonts repo, adds all available WOFF/WOFF2 weights via the CSS2 API, writes OFL.txt, and generates an SCSS snippet.
✨ Features:
- Variable font detection - Automatically detects and handles variable fonts correctly
- Smart subsetting - Uses Google's optimized WOFF2 subsets (20-50KB per font)
- Optional TTF conversion - Convert TTF to WOFF/WOFF2 for full unicode coverage
- No duplicates - Intelligently avoids downloading the same file multiple times
Installation
From PyPI (recommended):
pip install fontdownloader
From source (development):
pip install -e .[dev]
Optional Dependencies
For TTF to WOFF/WOFF2 conversion (full unicode support):
pip install fonttools[woff,woff2] brotli
Commands
Search
fontdownloader search "Roboto"
fontdownloader search "Inter" --details # Show variant details
Download one or more families (consolidated)
# Single font (Google's optimized subsets)
fontdownloader download "Inter"
# Multiple fonts
fontdownloader download "Inter" "Roboto" "Lora"
# From file (one name per line)
fontdownloader download --file fonts.txt
# Force reinstall
fontdownloader download "Inter" --force
# Convert TTF to WOFF/WOFF2 for full unicode coverage
fontdownloader download "Inter" --convert-ttf
What gets downloaded:
- TTF/OTF/TTC files + OFL.txt (from ZIP or google/fonts repo)
- WOFF/WOFF2 files via CSS2 API (all weights 100-900, normal/italic)
- For variable fonts: Downloads once per style (no duplicates!)
- SCSS file in
assets/scss/<Family>.scsswith proper @font-face rules - All files in
assets/fonts/<Family>/
Generate SCSS only
fontdownloader generate-scss "Roboto"
- Regenerates
assets/scss/Roboto.scssbased on current files inassets/fonts/Roboto/
Update Font Catalog
fontdownloader update-catalog
fontdownloader update-catalog --force # Force update even if cache is fresh
Download Multiple Popular Fonts
fontdownloader download-all --limit 50
fontdownloader download-all --limit 100 --convert-ttf # With TTF conversion
Output Structure
assets/
├── fonts/
│ └── Inter/
│ ├── Inter-normal.woff2 # Variable font (100-900 weights)
│ ├── Inter-italic.woff2 # Variable italic
│ ├── Inter[opsz,wght].ttf # Full TTF (if available)
│ └── OFL.txt # License
└── scss/
└── Inter.scss # @font-face rules
Font Formats Explained
Google's WOFF2 Subsets (Default)
- ✅ Small files (20-50KB per font) - Fast page loads
- ✅ Web optimized - Google's subsetting strategy
- ✅ No extra tools needed
- ❌ Limited unicode coverage (Latin, Cyrillic, Greek subsets)
TTF Conversion (--convert-ttf)
- ✅ Full unicode coverage (all languages)
- ✅ Offline use without Google CDN
- ✅ Good compression (60% vs TTF)
- ❌ Larger files (300-400KB vs 25KB)
- ❌ Requires fonttools installation
See FONT_FORMATS_EXPLAINED.md for detailed comparison and use cases.
Variable Fonts
fontdownloader automatically detects variable fonts (fonts with weight/style axes) and handles them efficiently:
Before (old behavior):
- Downloaded Inter-100-normal.woff2, Inter-200-normal.woff2, ..., Inter-900-normal.woff2
- All were identical files (duplicates!)
- 18 files × 25KB = 450KB wasted space
After (v0.2.0+):
- Downloads Inter-normal.woff2 once (contains all weights 100-900)
- Generates proper CSS with weight ranges:
font-weight: 100 900; - 2 files × 25KB = 50KB total
Examples
Basic web project (Latin characters only)
fontdownloader download "Inter" "Roboto"
# Downloads ~50KB of optimized WOFF2 files per font
Multi-language website (need Cyrillic, Greek, etc.)
fontdownloader download "Inter" "Roboto"
# Downloads all Google subsets automatically (~175KB per font)
Full unicode coverage (convert TTF)
fontdownloader download --convert-ttf "Source Code Pro"
# Downloads TTF and converts to WOFF2 (~350KB per font)
Notes
- No API key required. If ZIP download is blocked, falls back to google/fonts GitHub repo.
- Optional: Set
GITHUB_TOKENenvironment variable to raise GitHub API rate limits. - Variable font support: Automatically detected and handled correctly.
- Smart caching: Font catalog cached for 24 hours to reduce API calls.
- The
assets/directory is gitignored by default.
Troubleshooting
"Missing characters in my downloaded font"
Google's WOFF2 subsets only include specific unicode ranges. Use --convert-ttf for full coverage:
fontdownloader download --convert-ttf "Inter"
"fonttools not found"
Install optional dependencies:
pip install fonttools[woff,woff2] brotli
"Downloaded many identical files"
Update to the latest version - variable font detection was added in v0.2.0:
pip install --upgrade fontdownloader
License
See LICENSE file.
Note: Downloaded fonts have their own licenses (typically OFL). See each font's OFL.txt file.
Metadata
Release files for fontdownloader 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fontdownloader-0.3.0.tar.gz | 21.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fontdownloader-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 41.9 kB
Release files / fontdownloader-0.3.0.tar.gz
| Download URL | fontdownloader-0.3.0.tar.gz |
|---|---|
| Size | 21.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
f6aec60d8d3f8c99c5ac4c9e28f5ef2075d97d8323369fbf0d8df154f3b8fe5e
|
|
BLAKE2b-256 checksum How to use checksums |
c4e765cb0599f7504a8f9a393638081e32b16afa1c37153d1963cad04f2f4f04
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / fontdownloader-0.3.0-py3-none-any.whl
| Download URL | fontdownloader-0.3.0-py3-none-any.whl |
|---|---|
| Size | 20.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c8aaad014e057259abda6d85c20705767f188c378b5227ba2bc961656bd2a0a2
|
|
BLAKE2b-256 checksum How to use checksums |
08cee4d1f55bdd321abc249acd8ae2d345e6aa004d58a7738d1d0fbf06543fb4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|