Context
PR #57 solved the immediate problem of missing named exports by code-generating all ~1,923 Google Font exports from the Google Fonts API. This works and tree-shakes correctly, but it requires maintaining a generated file that needs periodic re-runs as Google adds new fonts.
How Next.js Does It
Next.js handles next/font/google entirely at compile time via an SWC transform:
- SWC detects
import { Inter } from 'next/font/google'
- Rewrites
const inter = Inter({...}) into a CSS import with query params
- A webpack loader downloads fonts and generates
@font-face CSS at build time
The next/font/google module in Next.js only contains declare function type stubs. There's zero runtime JavaScript. The font system is a compile-time illusion.
Proposed Approach
We could implement a similar pattern using a Vite transform hook:
- Detect
import { X } from 'next/font/google' in the importing file
- Rewrite it to
import { createFontLoader } from 'vinext/shims/font-google-base'; const X = createFontLoader("X Name");
- The transform derives the font family name from the export name (same logic the Proxy already uses)
Benefits
- No generated file to maintain (no need to re-run a script when Google adds fonts)
- Works for any font automatically, including ones Google hasn't added yet
- Zero bundle overhead (only fonts actually used get
createFontLoader calls)
- Closer to how Next.js handles it architecturally
Considerations
- Need to handle edge cases: re-exports, dynamic imports, barrel files
- IDE autocomplete would still need the
.d.ts declarations file (could keep generating that separately)
- Must work correctly in all three Vite environments (RSC, SSR, client)
Current State
The generated catalog from PR #57 works well and is the right solution for now. This issue tracks exploring the transform approach as a future improvement.
Context
PR #57 solved the immediate problem of missing named exports by code-generating all ~1,923 Google Font exports from the Google Fonts API. This works and tree-shakes correctly, but it requires maintaining a generated file that needs periodic re-runs as Google adds new fonts.
How Next.js Does It
Next.js handles
next/font/googleentirely at compile time via an SWC transform:import { Inter } from 'next/font/google'const inter = Inter({...})into a CSS import with query params@font-faceCSS at build timeThe
next/font/googlemodule in Next.js only containsdeclare functiontype stubs. There's zero runtime JavaScript. The font system is a compile-time illusion.Proposed Approach
We could implement a similar pattern using a Vite
transformhook:import { X } from 'next/font/google'in the importing fileimport { createFontLoader } from 'vinext/shims/font-google-base'; const X = createFontLoader("X Name");Benefits
createFontLoadercalls)Considerations
.d.tsdeclarations file (could keep generating that separately)Current State
The generated catalog from PR #57 works well and is the right solution for now. This issue tracks exploring the transform approach as a future improvement.