vercel/next.js
font
Purpose
@next/font (legacy) and the built-in next/font provide automatic font optimization. Users import next/font/google or next/font/local, and the framework downloads the font files at build time, hashes them into the static asset directory, generates an inline CSS rule for font-family and @font-face, and inlines a preload tag in the document head. No client-side flash-of-unstyled-text and no requests to Google's font servers at runtime.
Source: packages/font/src/.
Directory layout
packages/font/
├── src/
│ ├── constants.ts # Default ranges, file types, etc.
│ ├── format-available-values.ts # Error formatting helper
│ ├── google/ # next/font/google implementation
│ ├── local/ # next/font/local implementation
│ ├── next-font-error.ts # Custom error class
│ └── types.ts
├── google/ # Public re-export shape
├── local/ # Public re-export shape
├── fontkit.js # Wrapper for the fontkit dependency
└── package.jsonThe google/ and local/ directories at the package root are minimal re-export shims so user code can write import { Inter } from 'next/font/google'.
How it runs
graph TD
UserCode["import { Inter } from<br/>'next/font/google'"] --> SwcTransform["SWC transform<br/>crates/next-custom-transforms/<br/>next-font"]
SwcTransform --> Loader["next-font Webpack loader<br/>(or Turbopack equivalent)"]
Loader --> GoogleResolver["packages/font/src/google/"]
GoogleResolver --> Download["fetch Google CSS,<br/>fetch font files,<br/>hash + write to static/"]
Download --> Manifest["next-font-manifest.json"]
Loader --> InjectCSS["inject @font-face + className"]
Manifest --> Render["build/static-paths<br/>writes preload tags"]The transform in crates/next-custom-transforms/ rewrites the user's import call into a call to a runtime loader. That loader, when run during the build, calls into packages/font/src/google/ or packages/font/src/local/ to do the actual font fetching and processing.
The next-font-manifest.json produced at build time tells the runtime which preload tags to inject into the <head> of each page.
Google fonts
packages/font/src/google/ contains:
- A static map of all available Google fonts (regenerated periodically by
scripts/update-google-fonts.js) - The
getFontDefinition()helper that turns a user import into a download URL - The CSS parser that extracts
@font-facerules and unicode ranges from the Google CSS response - The font-file fetcher
When the build runs, each unique combination of font family + weights + subsets is downloaded once and hashed into a stable filename so cache keys stay valid across builds.
Local fonts
packages/font/src/local/ is much smaller. It wraps a user-supplied font file path, copies the file into the static asset directory, and emits the right @font-face rule. Optional subsetting / variable-axis handling uses the fontkit dependency (wrapped in fontkit.js).
SWC transform
The transformation that rewrites import { Inter } from 'next/font/google' into a call to the loader lives in Rust at crates/next-custom-transforms/. This is what makes the Inter() factory call execute at build time rather than at runtime.
Refresh
The font catalog is updated by:
pnpm update-google-fontsThis runs scripts/update-google-fonts.js, which scrapes the Google Fonts API and rewrites the static catalog under packages/font/src/google/.
A weekly GitHub Action (.github/workflows/update_fonts_data.yml) runs the update automatically and opens a PR.
Key source files
| File | Purpose |
|---|---|
packages/font/src/google/ |
Google fonts: catalog + downloader |
packages/font/src/local/ |
Local fonts |
packages/font/src/constants.ts |
Defaults |
crates/next-custom-transforms/src/transforms/next_font/ |
The SWC transform that rewrites font imports |
scripts/update-google-fonts.js |
Refreshes the Google catalog |
Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.