unifont
  • All fonts Browse or filter the whole catalogue
  • Compare providers One family, every CDN, side by side
  • Documentation Install, providers, custom providers
  • HTTP API The endpoints this site is built on

Caching

Provider metadata barely changes. Cache it, and cold starts stop hurting.

By default unifont caches in memory, which lasts as long as the process does. For a build tool or a server that's usually the wrong choice, because every restart pays the full round trip for the same getFontProperties('Inter') call.

The storage option takes anything with getItem and setItem, so anything unstorage can drive will work:

ts

import { createUnifont, providers } from 'unifont'
import { createStorage } from 'unstorage'
import fsDriver from 'unstorage/drivers/fs-lite'

const storage = createStorage({
  driver: fsDriver({ base: 'node_modules/.cache/unifont' }),
})

const unifont = await createUnifont([providers.google()], { storage })

Entries expire after a week, and they're keyed by unifont version, so upgrading the package throws them away rather than handing you data in an old shape.

In Nitro or Nuxt

Nitro already has storage, so give unifont a thin adapter over it:

ts

// server/utils/unifont.ts
import { createUnifont, providers } from 'unifont'

let instance: ReturnType<typeof createUnifont> | undefined

export function useUnifont() {
  const cache = useStorage('unifont')
  instance ??= createUnifont([providers.google()], {
    storage: {
      getItem: key => cache.getItem(key),
      setItem: (key, value) => cache.setItem(key, value),
    },
  })
  return instance
}

That's what this site does. Point the unifont bucket at the filesystem in development and at KV in production, and family pages come back warm.

What is worth caching

Providers cache two things behind the same interface. There's the family index built at startup: listFonts data, large, and it hardly ever changes. And there are per-family results, keyed by the options you passed: small, but a lot of them. Both go through the storage you provide, so one driver covers it.

Keep the instance around too, as the example above does. createUnifont() starts up every provider, and for some that means fetching the whole family index. Creating one per request throws that work away.