Astro integration that subsets your font files so you get significantly smaller font sizes and faster loading speeds
npm install @forthgoing/subfont
Automatically subset, compress, and optimize your local fonts - dramatically smaller font files, faster paint times, better Lighthouse scores.
Explore the docs
Report Bug
·
Request Feature




Subfont is a powerful Astro integration that takes your local fonts (TTF, OTF, WOFF2) in /src/assets/fonts, analyzes all actual text content across your .astro, .md, .mdx, .ts, etc. files, and generates WOFF2 subsets with only the text you use.
The result? Fonts that are often 70-95% smaller than the originals, with zero visual difference, leading to faster page loads, lower data usage (especially on mobile), improved Largest Contentful Paint (LCP), and significantly better Lighthouse / Core Web Vitals scores.
- Only includes glyphs actually used in your site
- Automatic WOFF2 conversion & compression (TTF/OTF → highly optimized WOFF2)
- Original font source files - Keeps your original fonts saved so when you use more characters in your site it automatically gets added to the optimized fonts.
- Variable font support
- Smart caching - only re-processes changed fonts or when content changes
- Font manifest generation
- Full control of your fonts Preload, display, alias, etc..
- Duplicate & symlink protection
Most font optimization tools either:
- Require manual unicode-range lists
- Depend on Google Fonts / external services
- Don't update subsets when content changes
- Rely on bloated python scripts or wrappers like glyphhanger
@forthgoing/subfont stands out because it:
- Core fully built in Rust.
- Fast and lightweight
- Fully configurable
- Keeps your original font files for updating your optimized fonts
- Doesn't require installing anything extra
- Caches intelligently using content hash + font hash + version
Requires:
- Node 18+
- Astro 4+
- Fonts in /src/assets/fonts
Supported source formats:
- .ttf
- .otf
- .woff2
WOFF is not supported and will be skipped gracefully.
---
1. Add the dependency:
``sh`
npm install @forthgoing/subfontor
pnpm add @forthgoing/subfontor
yarn add @forthgoing/subfont
2. Add the plugin to astro.config.(ts|js|mjs):
`typescript
import subfont from "@forthgoing/subfont";
export default defineConfig({
integrations: [subfont()],
});
`
3. Import tags into your Layout.astro:
`javascript`
import SubfontHead from "forthgoing:subfont/head";
import SubfontBody from "forthgoing:subfont/body";
Usage inside Layout.astro:
`html`
...
4. Place your fonts in src/assets/fonts:
``
src/assets/fonts/
├── Inter-Regular.ttf
├── Inter-Italic.ttf
├── PragmataPro.woff2
└── MyCustomFont-Variable.ttf
After setup, just run npm run dev or npm run build
And use your font normally:
``
h1 {
font-family: 'InterRegular',
}
Create this file at the root of your project.
`typescript
import type { SubfontConfig } from "@forthgoing/subfont";
const config: SubfontConfig = {
inter: {
alias: "Inter",
display: "swap",
weight: "100 900",
tagPlacement: "head", // "head" | "body"
stylePlacement: "head",
preload: true,
},
pragma: {
tagPlacement: "head",
weight: "100 900",
stylePlacement: "head",
},
// Add more font families...
};
export default config;
`
`typescript`
subfont({
assetsFolder: "src/assets", // default
fontsSubdir: "fonts", // default = "fonts"
hashFonts: true, // append content hash to filename (great for caching)
})
1. Scans all source files and collects used characters
2. Computes content hash
3. For each font:
- Checks cache
- Subsets to only used glyphs
- Converts to WOFF2
- Keeps your original fonts
- Removes old variants
4. Injects , @font-face via SubfontHead / SubfontBody
Contributions are welcome!
1. Fork the project
2. Create your feature branch
3. Commit your changes
4. Push to the branch
5. Open a pull request
Distributed under the MIT License. See LICENSE` for more information.