metadata
title: FontMap
short_description: Visual font explorer powered by FontCLIP
emoji: πΊοΈ
colorFrom: indigo
colorTo: blue
sdk: static
pinned: false
app_build_command: CI=false npm run build
app_file: build/index.html
FontMap
An interactive map of 1,100+ Google Fonts organized by visual similarity, using FontCLIP embeddings and UMAP dimensionality reduction.
Inspired by IDEO's Font Map (2017, Kevin Ho) β rebuilt from scratch with modern ML, fully open source, and documented.
Features
- Visual similarity map β fonts that look alike are physically close together
- 1,192 Google Fonts β full catalog, family variants merged
- Click any font β see details + 5 nearest visual neighbors
- Filter by category β serif, sans-serif, display, handwriting, monospace
- Category colors β toggle color coding to see how clusters map to official categories
- Search β find any font by name
- Zoom & pan β explore the full map with smooth D3.js navigation
How it works
Font images βββ FontCLIP (512D) βββ PCA (50D) βββ UMAP (2D) βββ Interactive map
β
k-NN (similar fonts)
- Render β each font is rendered as a 224Γ224 composite glyph image
- Embed β FontCLIP (CLIP ViT-B/32 fine-tuned for typography) encodes each image into a 512-dimensional vector
- Reduce β PCA compresses to 50D, then UMAP with spectral initialization projects to 2D (n_neighbors=12, min_dist=1.0)
- Merge β font family variants (Regular, Bold, Italicβ¦) are fused into a single representative point
- Neighbors β k-NN is computed in the original 512D space for "similar fonts" recommendations
- Visualize β React + D3.js renders all glyphs from a single SVG sprite (zero individual network requests)
Getting started
Run locally
git clone https://github.com/tfrere/fontmap.git
cd fontmap
npm install
npm start
Open http://localhost:3000.
Build for production
npm run build
Deploy to Hugging Face Spaces
The project is configured for HF Spaces static SDK with a build step:
sdk: static
app_build_command: "CI=false npm run build"
app_file: "build/index.html"
Regenerating the map
The embedding pipeline lives in src/typography/new-pipe/. See its README for full instructions.
Quick summary:
# 1. Generate FontCLIP embeddings (requires Python + GPU, ~1h one-time)
cd src/typography/new-pipe/python-pipeline
python run_fontclip.py
# 2. Test different UMAP configurations
cd ..
npm run batch-umap
npm run copy-to-debug
# Compare visually at http://localhost:3000/#/debug-umap
# 3. Deploy chosen config to production
npm run deploy fontclip-spectral
Project structure
fontmap/
βββ public/
β βββ data/
β β βββ char/ # Individual glyph SVGs (~1,200 files)
β β βββ sentences/ # Sentence preview SVGs
β β βββ font-sprite.svg # All glyphs in a single sprite (3 MB)
β β βββ typography_data.json # Font positions + metadata
β βββ debug-umap/ # Pre-computed UMAP configs for comparison
βββ src/
β βββ components/
β β βββ FontMap/ # Main map component (production)
β β βββ DebugUMAP/ # UMAP comparison tool (development)
β β βββ FontMapV2/ # Experimental canvas renderer
β βββ hooks/ # Shared hooks (data loading, dark mode)
β βββ store/ # Zustand state management
β βββ typography/new-pipe/ # Embedding + UMAP generation pipeline
β βββ python-pipeline/ # FontCLIP + PCA + UMAP (Python)
βββ package.json
Tech stack
| Layer | Tech |
|---|---|
| Frontend | React 19, D3.js v7, Zustand |
| Rendering | SVG sprite + D3 zoom/pan |
| Embeddings | FontCLIP (CLIP ViT-B/32 fine-tuned for typography) |
| Dim. reduction | PCA + UMAP (spectral init) via umap-learn |
| Hosting | Hugging Face Spaces (static SDK) |
Credits
- FontCLIP β Typography-aware CLIP model by KInIT
- IDEO Font Map β Original inspiration by Kevin Ho (2017)
- Google Fonts β Font catalog
- UMAP β Dimensionality reduction by Leland McInnes
License
MIT
