Geist

Vercel's Geist Sans, Mono, and Pixel typefaces, pre-packaged as drop-in Next.js font loaders.

Library
npm
v1.8.2
3,670 stars
OFL-1.1

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum. How we score it →
71 /100 Good
Development Activity 72
Maintenance 68
Community 52
Maturity 52
Momentum 40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation. How we score it →
59 /100 Fair
Architecture 62
Code Quality 45
Innovation 38
Learning Curve 90

Geist is the official npm distribution of Vercel’s Geist type family — Geist Sans, Geist Mono, and the five-variant Geist Pixel display faces — designed by Vercel in collaboration with Basement Studio and Andres Briganti around the principles of classic Swiss typography. The package ships variable and non-variable WOFF2 builds pre-wired through next/font/local, so each face becomes a NextFontWithVariable export ready to attach via className or CSS variable.

Rather than requiring consumers to self-host font files or hand-configure @font-face rules, geist exports one import per face (geist/font/sans, geist/font/mono, geist/font/pixel, plus non-variable fallbacks) that Next.js optimizes automatically — inlining font metadata, avoiding layout shift, and eliminating any runtime request to an external font CDN.

What You Get

  • Geist Sans and Geist Mono variable fonts preloaded via next/font/local with weights 100-900 in a single ~30kb variable file, plus non-variable fallbacks for browsers without variable-font support.
  • Five Geist Pixel display variants (Square, Grid, Circle, Triangle, Line), each exported separately with its own CSS variable and monospace fallback stack.
  • Zero-config Next.js optimization: every export is a NextFontWithVariable, so Next.js inlines font metadata and eliminates font-swap layout shift automatically.
  • Tailwind CSS v3 and v4 integration via documented CSS variables (—font-geist-sans, —font-geist-mono, —font-geist-pixel-*) that plug directly into theme config.
  • SIL Open Font License (OFL-1.1) fonts — free for commercial and personal use with no attribution required in the shipped binaries.

Common Use Cases

  • Next.js App Router typography - importing GeistSans and GeistMono into app/layout.js to set the site-wide font stack in one line.
  • Vercel-style dashboards and marketing sites - teams matching Vercel’s own visual identity without self-hosting font files.
  • Code-heavy interfaces - using GeistMono for code editors, terminals, and diagrams that need a monospace face paired to GeistSans.
  • Retro/display branding - using GeistPixel variants for headlines and logos wanting a pixel aesthetic without sourcing custom font files.

Under The Hood

Architecture

The repository is a monorepo split between a Python-based font-build toolchain at the root (Makefile, scripts/.py, sources/, requirements.txt) that compiles the Geist type family into variable and static WOFF2/TTF binaries under fonts/, and packages/next/ — the published npm surface — which re-packages a curated subset of those binaries (Geist-Variable.woff2, GeistMono-Variable.woff2, five GeistPixel-.woff2 files) behind deliberately thin JS modules (dist/sans.js, dist/mono.js, dist/pixel.js) that each call next/font/local with a fixed src/variable/fallback configuration. A legacy top-level geist/font entry point re-exports the same fonts as deprecated aliases alongside the current per-face entry points (geist/font/sans, geist/font/mono, geist/font/pixel), so the wrapper layer’s only real responsibility is keeping those two export surfaces in sync as fonts are added or renamed.

Tech Stack

The published package’s package.json declares next as a peerDependency (>=13.2.0), @changesets/cli as its sole devDependency, type: module with an exports map covering six subpaths, and is built/released with pnpm (packageManager pinned to pnpm@10.33.4). Versioning and npm publishing are automated through Changesets CI, triggered on merges to main via .github/workflows/ci.yaml and guard-prerelease.yaml. The font-build side of the monorepo runs a separate Python toolchain (requirements.txt / requirements-test.txt) driven by a Makefile to generate and customize the underlying variable fonts before they’re copied into the npm package’s dist/fonts directory.

Code Quality

No JavaScript/TypeScript test files or test script exist in packages/next — the wrapper modules are a handful of declarative next/font/local calls with no logic to unit test, and this is stated here explicitly rather than assumed. Type safety is provided through hand-authored .d.ts declaration files with extensive JSDoc (including @deprecated annotations distinguishing the legacy geist/font exports from the current per-face ones), and naming is consistent across all exports (GeistSans, GeistMono, GeistPixelSquare/Grid/Circle/Triangle/Line). No linter configuration is present inside packages/next itself; CI at the repo root runs build/release checks but no dedicated JS test suite was found.

API Design The public API is intentionally minimal and ergonomic: one import per typeface variant, each already shaped as a NextFontWithVariable so consumers only ever touch .className or .variable. Getting started requires a single import line and no configuration; the only friction documented is a transpilePackages entry needed on Next.js versions older than 15, called out explicitly in the README with the exact error messages it fixes. Comprehensive fallback font stacks are baked into the Mono and Pixel exports so unstyled text remains legible before the webfont loads, and README coverage extends to Tailwind v3 and v4 wiring, App Router and Pages Router examples, and per-variant CSS variable names.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers