https://github.com/forthgoing/subfont
Subfont is an Astro drag-and-drop integration that automatically subsets your web fonts to include only the characters actually used on your pages.
https://github.com/forthgoing/subfont
astro font lighthouse optimization performance rust speed subset web
Last synced: 5 months ago
JSON representation
Subfont is an Astro drag-and-drop integration that automatically subsets your web fonts to include only the characters actually used on your pages.
- Host: GitHub
- URL: https://github.com/forthgoing/subfont
- Owner: forthgoing
- License: mit
- Created: 2026-01-25T10:15:07.000Z (5 months ago)
- Default Branch: main
- Last Pushed: 2026-01-25T15:41:21.000Z (5 months ago)
- Last Synced: 2026-01-25T18:58:05.535Z (5 months ago)
- Topics: astro, font, lighthouse, optimization, performance, rust, speed, subset, web
- Language: Rust
- Homepage:
- Size: 8.79 MB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README

Subfont - Ultra-optimized font subsetting for Astro
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
[](https://www.npmjs.com/package/@forthgoing/subfont)
[](https://astro.build)
[](https://opensource.org/licenses/MIT)
[](https://github.com/forthgoing/subfont)
Table of Contents
- About The Project
- Key Features
- What Makes It Stand Out
-
Getting Started
- Usage
- Configuration
- How It Works
- Contributing
- License
## About The Project
**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.
### Key Features
- **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**
### What Makes Subfont Stand Out
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**
## Getting Started
### Prerequisites
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.
---
## Installation
1. Add the dependency:
```sh
npm install @forthgoing/subfont
# or
pnpm add @forthgoing/subfont
# or
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
```
## Usage
After setup, just run `npm run dev` or `npm run build`
And use your font normally:
```
h1 {
font-family: 'InterRegular',
}
```
## Configuration
### Subfont config `subfont.config.ts`
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;
```
### Plugin options `astro.config.ts`
```typescript
subfont({
assetsFolder: "src/assets", // default
fontsSubdir: "fonts", // default = "fonts"
hashFonts: true, // append content hash to filename (great for caching)
})
```
## How it works
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
## Contributing
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
## License
Distributed under the MIT License. See `LICENSE` for more information.