Introduction
What unifont does, what it doesn't, and why.
No two font CDNs are accessed in the same way.
Google returns a stylesheet you have to parse. Fontshare returns JSON, with its own names for weights. Fontsource publishes to npm. And Adobe needs custom configuration and a project id.
unifont is a single layer for all font providers. Call it with a family and you'll get back a consistent response with weights, styles, subsets, unicode ranges and @font-face data.
import { createUnifont, providers } from 'unifont'
const unifont = await createUnifont([
providers.google(),
providers.fontshare(),
])
const { fonts, fallbacks } = await unifont.resolveFont('Switzer')What it doesn't do
unifont reads metadata. It doesn't download fonts, subset them, generate CSS, or cache anything for you. You get the data back and decide what to do with it.
That's deliberate. Check out fontless for zero-config integration for Vite, or the @nuxt/fonts, the equivalent for Nuxt. Or build your own integration!
Where it runs
Node, Bun, Deno, workers, and the browser.
In a browser or a web container, CORS blocks the provider APIs, so requests go through a proxy instead. See Browser and web containers.
This site
Every page here is also an endpoint: the HTTP API is described by /openapi.json, there is an MCP server at /mcp, /llms.txt indexes the site for agents, and any prose page will answer in markdown if you ask for text/markdown or append .md to its path.
Everything on unifont.dev comes from unifont. The catalogue is listFonts(), the family pages are getFontProperties() and resolveFont(), and the type you're reading is set with a stylesheet built from resolved metadata.