fontmap / README.md
tfrere's picture
tfrere HF Staff
chore: clean up repo for open source release
fc2a05d
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.

Live demo

FontMap screenshot

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)
  1. Render β€” each font is rendered as a 224Γ—224 composite glyph image
  2. Embed β€” FontCLIP (CLIP ViT-B/32 fine-tuned for typography) encodes each image into a 512-dimensional vector
  3. Reduce β€” PCA compresses to 50D, then UMAP with spectral initialization projects to 2D (n_neighbors=12, min_dist=1.0)
  4. Merge β€” font family variants (Regular, Bold, Italic…) are fused into a single representative point
  5. Neighbors β€” k-NN is computed in the original 512D space for "similar fonts" recommendations
  6. 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