vite-fonts
v0.2.0
Published
Zero-config font optimization for Vite - auto-detect fonts from CSS, download, and self-host with fallback metrics
Maintainers
Readme
vite-fonts
Zero-config font optimization for Vite - auto-detect fonts from CSS, download, and self-host with fallback metrics.
Similar to @nuxt/fonts but for any Vite project (Vue, React, Svelte, etc.).
Features
- Zero Configuration - Automatically detects
font-familydeclarations in your CSS - Multiple Providers - Bunny Fonts, Fontsource, local fonts (Google Fonts opt-in)
- Self-Hosting - Downloads and bundles fonts at build time for privacy and performance
- Fallback Metrics - Generates adjusted fallback fonts to reduce CLS (Cumulative Layout Shift)
- Caching - Persistent file cache for fast rebuilds and offline development
- Dev Server Support - Fonts work seamlessly in development mode
- Blazing Fast - Built with Rust-based tools (LightningCSS, oxlint, tsgo)
Installation
npm install vite-fonts
# or
pnpm add vite-fonts
# or
bun add vite-fontsUsage
Basic (Zero Config)
// vite.config.ts
import { defineConfig } from 'vite'
import fonts from 'vite-fonts'
export default defineConfig({
plugins: [fonts()],
})Then use fonts in your CSS as normal:
body {
font-family: 'Inter', sans-serif;
}
code {
font-family: 'Fira Code', monospace;
}The plugin will automatically:
- Detect the
font-familydeclarations - Resolve fonts from configured providers (Bunny, Fontsource, local)
- Download the font files
- Generate and inject
@font-facerules - Create fallback font metrics to reduce layout shift
With Configuration
// vite.config.ts
import { defineConfig } from 'vite'
import fonts from 'vite-fonts'
export default defineConfig({
plugins: [
fonts({
// Default options for all fonts
defaults: {
weights: [400, 700],
styles: ['normal', 'italic'],
subsets: ['latin', 'latin-ext'],
display: 'swap',
},
// Explicitly configure specific fonts
families: {
'Inter': {
weights: [400, 500, 600, 700],
styles: ['normal'],
},
'Fira Code': {
weights: [400, 700],
provider: 'fontsource',
},
},
// Provider configuration
providers: {
bunny: true, // Bunny Fonts (privacy-focused)
fontsource: true, // Fontsource (npm packages)
google: false, // Google Fonts (opt-in)
local: true, // Local fonts in public/
},
// Generate fallback font metrics (reduces CLS)
fallbacks: true,
// Caching
cache: true,
cacheDir: 'node_modules/.cache/vite-fonts',
// Output
assetsDir: 'fonts',
inject: 'inline', // 'inline' | 'external'
// Debug logging
debug: false,
}),
],
})Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| defaults | object | See below | Default font options |
| defaults.weights | number[] | [400, 700] | Font weights to download |
| defaults.styles | string[] | ['normal'] | Font styles to download |
| defaults.subsets | string[] | ['latin'] | Unicode subsets |
| defaults.display | string | 'swap' | Font display strategy |
| families | object | {} | Per-font configuration |
| providers | object | See below | Provider configuration |
| providers.bunny | boolean | true | Enable Bunny Fonts |
| providers.fontsource | boolean | true | Enable Fontsource |
| providers.google | boolean | false | Enable Google Fonts |
| providers.local | boolean\|object | true | Enable local fonts |
| fallbacks | boolean | true | Generate fallback metrics |
| cache | boolean | true | Enable font caching |
| cacheDir | string | node_modules/.cache/vite-fonts | Cache directory |
| assetsDir | string | 'fonts' | Output directory for fonts |
| inject | string | 'inline' | CSS injection method |
| debug | boolean | false | Enable debug logging |
How It Works
CSS Parsing - Uses LightningCSS (100x faster than PostCSS) to parse your CSS and extract
font-familydeclarations.Font Resolution - Uses unifont (same library as
@nuxt/fonts) to resolve fonts from multiple providers.Downloading - Font files are downloaded and cached using unstorage for fast rebuilds.
Fallback Generation - Uses fontaine to generate adjusted fallback
@font-facerules that reduce Cumulative Layout Shift (CLS).Injection -
@font-facerules are injected into your HTML, either as an inline<style>tag or as an external CSS file.
Supported Providers
- Bunny Fonts - Privacy-focused Google Fonts alternative
- Fontsource - Self-hostable open source fonts via npm
- Google Fonts - Opt-in, disabled by default
- Local - Font files in your
public/directory
Development
This project uses bleeding-edge tooling for maximum performance:
# Install dependencies
bun install
# Run development
bun run dev
# Run tests
bun run test
# Lint
bun run lint
# Type check (uses tsgo - 10x faster than tsc)
bun run typecheck
# Format
bun run format
# Full CI pipeline
bun run ciTooling
| Tool | Purpose | |------|---------| | Bun | Package manager & runtime | | tsdown | Rolldown-powered bundler | | tsgo | Go-based TypeScript type checker (10x faster) | | oxlint | Rust-based linter (100x faster than ESLint) | | oxfmt | Rust-based formatter (30x faster than Prettier) | | LightningCSS | Rust-based CSS parser | | Vitest | Vite-native test runner |
Credits
This plugin is built with:
- unifont - Font provider abstraction
- fontaine - Font fallback metrics
- lightningcss - CSS parsing
- unstorage - Caching
Inspired by @nuxt/fonts.
License
MIT
