npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

vite-font-extractor-plugin

v3.0.1

Published

Vite plugin for extracting glyphes by ligatures from font and creating new minimized fonts with them

Readme

vite-font-extractor-plugin

Vite plugin that extracts only the glyphs you use from font files — icon fonts, text fonts, or both. Supports Vite 5, 6, 7, and 8.

Before:  Material Icons   348 KB (all 2,000+ icons)
After:   Material Icons    12 KB (only 3 icons you need)   → 97% smaller

Features

  • Icon font minification — keep only the ligatures you use (Material Icons, FontAwesome, etc.)
  • Text font subsetting — keep only specific characters via ?subset= query
  • Zero-config auto mode — detects glyphs from CSS content: "..." automatically
  • Google Fonts optimization — appends &text= parameter for server-side subsetting
  • Works in build and dev — minifies fonts on-the-fly during development
  • Vite 5–8 support — compatible with both Rollup and Rolldown bundlers
  • Content-based hashing — output filenames change when config changes (cache-safe)
  • Live playground — see the plugin in action
  • Disk cache — skip re-minification on repeated builds

Quick Start

npm install vite-font-extractor-plugin

Zero-config (auto mode)

// vite.config.js
import FontExtractor from 'vite-font-extractor-plugin'

export default defineConfig({
    plugins: [FontExtractor()],
})

The plugin scans all CSS for content: "..." declarations, collects referenced glyphs, and strips everything else from font files.

Manual mode

Specify exactly which icons to keep:

FontExtractor({
    type: 'manual',
    targets: [
        {
            fontName: 'Material Icons',
            ligatures: ['close', 'menu', 'search', 'home'],
        },
    ],
})

Text Font Subsetting

Strip unused characters from text fonts like Roboto, Inter, or Open Sans.

Via CSS ?subset= query

/* Keep only Latin letters and digits */
@font-face {
    font-family: 'Roboto';
    src: url('./fonts/Roboto.woff2?subset=ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789') format('woff2');
}

/* Keep a Unicode range (e.g. Cyrillic) */
@font-face {
    font-family: 'Roboto';
    src: url('./fonts/Roboto.woff2?subset=U+0400-04FF') format('woff2');
}

/* Combine characters and Unicode ranges */
@font-face {
    font-family: 'Roboto';
    src: url('./fonts/Roboto.woff2?subset=ABC,U+0400-04FF') format('woff2');
}

Via JS import

Useful for runtime font loading (Rive, Canvas, PDF generators):

import fontUrl from './fonts/Roboto.woff2?subset=ABCabc'

// fontUrl is a clean URL to the subsetted font asset
rive.load({fonts: [fontUrl]})

Via plugin config

FontExtractor({
    type: 'manual',
    targets: [
        {
            fontName: 'Roboto',
            characters: 'ABCabc0123456789',
            engine: 'subset',
        },
    ],
})

Google Fonts

The plugin appends &text= to Google Font URLs, letting Google's servers do the subsetting:


<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
@import "https://fonts.googleapis.com/icon?family=Material+Icons";

Multi-family URLs are supported: family=Material+Icons|Roboto.

Caching

Enable disk cache to skip re-minification when fonts and config haven't changed:

FontExtractor({
    type: 'manual',
    targets: [{fontName: 'Material Icons', ligatures: ['close']}],
    cache: true,              // caches in node_modules/.font-extractor-cache
    // cache: './my-cache',   // or a custom path
})

The cache is automatically cleaned when cache is set to false.

Vite Compatibility

| Vite | Status | |------|--------------| | v5 | Stable | | v6 | Stable | | v7 | Stable | | v8 | Experimental |

Vite 8 uses Rolldown instead of Rollup. Icon font minification works fully. The ?subset= feature has known limitations — see ROADMAP for details.

API Reference

import FontExtractor from 'vite-font-extractor-plugin'

FontExtractor(options?: PluginOption): Plugin

PluginOption

| Option | Type | Default | Description | |------------|-------------------------------------------|-------------|-------------------------------------------| | type | 'auto' \| 'manual' | 'auto' | Glyph detection strategy | | targets | Target \| Target[] | — | Fonts to process. Required in manual mode | | cache | boolean \| string | — | Enable disk cache (or custom path) | | logLevel | 'info' \| 'warn' \| 'error' \| 'silent' | Vite config | Log verbosity | | apply | 'build' \| 'serve' | both | Restrict to build or dev mode | | ignore | string[] | — | Font names to skip entirely |

Target

| Option | Type | Description | |------------------|----------------------|--------------------------------------------------| | fontName | string | Must match font-family in CSS (without quotes) | | ligatures | string[] | Icon names to keep (e.g. ['close', 'menu']) | | raws | string[] | Raw Unicode characters to keep | | characters | string | Characters string for text font subsetting | | unicodeRanges | string[] | Unicode ranges (e.g. ['U+0400-04FF']) | | engine | 'icon' \| 'subset' | icon for icon fonts, subset for text fonts | | withWhitespace | boolean | Include whitespace glyphs (default: false) |

Troubleshooting

Font not being minified?

  • Check that fontName exactly matches the font-family value in your CSS @font-face (without quotes)
  • Make sure the font isn't in the ignore list

Warning: "has no minify options"?

  • The plugin found a @font-face but the font isn't in targets
  • Fonts with ?subset= URLs don't trigger this warning — they're processed automatically
  • To silence: add the font to targets, use ?subset=, or add to ignore

Google Font URL not transformed?

  • Use spaces in fontName: 'Material Icons', not 'Material+Icons'

Auto mode missing glyphs?

  • Auto mode only detects glyphs from CSS content: "..." properties
  • If icons are referenced by class name or JS, use manual mode instead

License

MIT

Contributing

Issues and pull requests are welcome on GitHub.