# Nuxt Fonts swaps Google Fonts links for locally subsetted font files

> Nuxt Fonts is a Nuxt module that resolves font families at build time, downloads them through a provider, subsets them to the characters your pages actually use, and serves them locally with metric overrides to avoid layout shift. It hit version 1.0.0 in October 2026, and its cost is that you take on font licensing as a build-time concern.

**nuxt/fonts** — Plug-and-play web font optimization and configuration for Nuxt apps.

- Repository: https://github.com/nuxt/fonts
- Website: https://fonts.nuxt.com
- Stars: 608 · Forks: 36
- Language: TypeScript
- License: MIT
- Published: 2026-10-22 · Updated: 2026-10-22 · Language: en
- Canonical page: https://hysenlabs.com/projects/nuxt-fonts

## What the module actually does at build time

Nuxt Fonts is described as plug-and-play custom web font optimization and configuration for Nuxt apps, and the feature list starts with zero-configuration required.

The mechanism is a build time pipeline. The module resolves the font families you reference in your CSS or templates, fetches the actual font files through a provider, and writes them into the output so the browser requests them from your own domain rather than from a third party CDN. That is the core of the value: self-hosting without writing a download script and a build hook yourself.

The optimisation part is where it earns its keep. Automatic font metric optimisation is powered by fontaine and capsize, which is the mechanism for avoiding Cumulative Layout Shift. Fonts are shipped with adjusted metrics so the space the browser reserves matches the space the substituted file actually takes, which is the difference between a font swap that pushes content down and one that does not. The repository topics list cls, css and performance, which tells you the module is aimed at the layout shift and page experience metrics rather than at file size alone.

The other half is caching. Build and dev time font caching is powered by unstorage, so the same font file is not downloaded again on every build. That matters more than it sounds: without it, every CI run would re-fetch every family, and a rate limited font CDN would make your builds flaky.

There is also a full local download support option, described as available until nuxt/assets lands, which is a telling phrase. The module currently has to do the asset handling itself because the Nuxt asset pipeline does not yet cover it.

## Eight built-in providers, and a path to writing your own

The provider system is how the module gets font files. The built-in list is given as google, googleicons, bunny, fontshare, fontsource, adobe, npm and local, with more welcome.

Each of those solves a different sourcing problem. google and googleicons point at the Google Fonts service, which is the default most people arrive from. bunny is an alternative host for the same kind of catalogue. fontshare supplies the Fontshare families. fontsource resolves npm-published font packages, which is the route for teams that already manage their font assets as packages. adobe covers the Adobe font families. local resolves a family from files already on your machine, which is what you want when you have licensed fonts you cannot redistribute from a CDN.

The local provider and the local download support option are the two escape hatches, and they are the ones that matter for organisations with a licensing policy. If a family may not be fetched from a third party host, you point the provider at your own files, and the module still handles subsetting, metrics and caching.

For everything else there are custom providers for full control. The documentation points to the Nuxt Fonts RFC on the Nuxt discussions for the full details and discussion, and the README itself is thin, pointing to the documentation site at fonts.nuxt.com rather than describing the configuration keys. That is a reasonable division for a module with a large option surface, but it means the README will not answer most of your questions.

A playground is available on StackBlitz for the basic setup, which is the fastest way to see the module working before you add it to a real project.

## Installing it takes one command

The installation is a single command, given in the documentation as adding the @nuxt/fonts dependency to your project:

```sh
npx nuxt module add fonts
```

That is the whole setup for a consumer. The module is published as @nuxt/fonts at version 1.0.1, so the package name on npm differs from the command you type, which is the usual Nuxt convention where the module add command takes the short name.

For contributors, the repository documents a different path. You clone the repository, enable Corepack with corepack enable, install dependencies with pnpm install, run pnpm dev:prepare to generate type stubs, and use pnpm dev to start the basic playground in development mode. The package scripts confirm the shape of that workflow: dev is nuxt dev playgrounds/basic, and dev:prepare is a long chained command that builds the module stub, prepares the module, and then runs nuxt prepare against each of the playgrounds.

Those playgrounds are worth knowing about, because they show the module working with several styling setups rather than only the default. The scripts point at a basic playground, a nuxt5 playground, a scss playground, a tailwindcss playground and an unocss playground, each with its own dev script. If you are on Tailwind or UnoCSS, seeing the module work in that playground before committing is the fastest way to know whether the font family names resolve the way you expect.

## The package ships as a module with an optional utility entry point

The package manifest explains how the module is consumed, and there is one detail worth pulling out.

The package name is @nuxt/fonts, the version is 1.0.1, the type is module, and the license is MIT. The exports map has two entries: the root points at ./dist/module.mjs and there is a separate ./utils entry pointing at ./dist/utils.mjs. Type declarations are provided for both through typesVersions.

That utils entry is the one to pay attention to. It means the font resolution logic is exposed as an importable utility, not only as a build-time side effect. If you have a place in your codebase that needs to resolve a font family to a URL, for example a component that sets a src for an image or a document generator, you can call the same resolution code rather than reimplementing it.

The build system is the standard Nuxt module tooling. The build script is nuxt-module-build prepare followed by nuxt-module-build build, and prepack runs the build. The only files published are the dist directory.

The peer dependencies are informative about what the module needs from your project. lightningcss at ^1.33.0 and subset-font at ^2.9.0 are both listed as optional peer dependencies, and both are marked optional in peerDependenciesMeta. That tells you the module can work without them, but will do more without them: lightningcss is the CSS transformer that lets it rewrite font URLs in processed stylesheets, and subset-font is the subsetter. If you are on a setup where neither is present, expect the subsetting and URL rewriting to be skipped rather than the module failing.

## Where the build time approach breaks down

The central constraint follows from the mechanism. Subsetting happens at build time, which means the character set of your fonts is decided when you build, not when a user requests a page.

That is fine for a marketing site, a documentation site, an application whose interface strings are all in the source. It is a problem when text is generated at runtime, when user input is displayed, or when a content management system holds content you did not compile against. A build time subset for the characters the build saw will drop the characters a user typed. Broadening the subset to include the full Unicode range for a CJK font defeats the purpose of subsetting and produces very large files, so the usual resolution is to exclude those families from subsetting, which means losing the layout shift protection as well.

The second limitation is network access at build time. The providers are remote services. If your CI environment cannot reach them, the build fails, and a font CDN outage becomes your build outage. The local provider and the local download support option exist for exactly this case, and they are the configuration to reach for in a restricted environment, but they require you to already have the font files and the rights to them.

The third is the licensing question, which the module does not handle for you. A family that is free for personal use on a website may not be free to embed in a commercial product or to redistribute to your users. The module will happily download it. Nothing in the documentation appears to check the licence terms of what it fetches.

## MIT licensed and freshly versioned, but the release history is short

The licence is MIT, published under the MIT License with the LICENSE file at the repository root, which is the expected and uncomplicated case for a Nuxt module.

The release history is recent and short. Version 1.0.0 was published on 2026-10-11, version 1.0.1 on the same day, and before that v0.14.0 on 2026-02-14. The last push was on 2026-10-20.

That gap between 0.14.0 in February and 1.0.0 in October is a major version bump after eight months, which usually means the API was allowed to move before being frozen. If you were on the 0.x line, the upgrade to 1.0 is the point at which you should read the changelog rather than assume the config keys still work.

The 1.0.0 and 1.0.1 releases on the same day also suggest a release process that was exercised immediately after the major version, which is normal for a module going stable.

The repository is a standard Nuxt module repository. Alongside the source in src/ there is a docs/ directory, a playgrounds/ directory with the five setups, a test/ directory, a build.config.ts, an eslint.config.js, a vitest.config.ts, a pnpm-workspace.yaml with a pnpm-lock.yaml, a renovate.json for dependency updates, a CODEOWNERS file, a .nuxtrc and an .editorconfig. Tests run through vitest with coverage, and there is a separate type test script using vue-tsc.

## Conclusion

Nuxt Fonts suits a Nuxt team that has decided against calling Google Fonts at runtime, wants the font files self-hosted, and can accept a build step that needs network access and a font licence per family. It is the wrong choice if your pages render text that only exists at runtime, since the subsetting is a build time operation, and the wrong choice if you need a provider or subsetting engine this module does not cover, since the built-in list is short. Before adopting it, check the licence of every family you use, since the module downloads them for you and the licence travels with the files you ship, and confirm the local provider and the local download support meet your needs if you cannot reach a font CDN from your build environment.

## FAQ

### How do I install Nuxt Fonts in a Nuxt project?

Run npx nuxt module add fonts, which installs the @nuxt/fonts dependency. The module is described as requiring zero configuration, and it resolves font families at build time, downloads them through a provider and serves the subsetted files locally.

### Which font providers does Nuxt Fonts support?

The built-in providers are google, googleicons, bunny, fontshare, fontsource, adobe, npm and local, and the documentation notes more are welcome. Custom providers are supported for full control, and the local provider covers families that cannot be fetched from a third party host.

### Does Nuxt Fonts avoid layout shift when fonts load?

Automatic font metric optimisation is powered by fontaine and capsize, which adjusts font metrics so the reserved space matches the rendered file and reduces Cumulative Layout Shift. The optional peer dependencies lightningcss and subset-font are what enable the URL rewriting and subsetting parts of that pipeline.

## Sources

- [License: MIT](https://github.com/nuxt/fonts/blob/main/LICENSE)
- [nuxt/fonts on GitHub](https://github.com/nuxt/fonts)
- [Project website](https://fonts.nuxt.com)
- [README](https://github.com/nuxt/fonts/blob/main/README.md)
- [Releases](https://github.com/nuxt/fonts/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/nuxt-fonts
