# API reference

> Every export, option and signature in one place.

Three runtime exports, one of them a namespace, and the types behind them:

```ts
import { createUnifont, defineFontProvider, providers } from 'unifont'
import type { FontFaceData, FontProperties, ResolveFontOptions, ResolveFontResult, Unifont } from 'unifont'
```

## `createUnifont()`

```ts
function createUnifont<T extends [Provider, ...Provider[]]>(
  providers: T,
  options?: UnifontOptions,
): Promise<Unifont<T>>
```

Providers are tried in order. The first one that knows a family answers.

Awaiting this starts every provider, and some fetch a whole family index to do it. Keep the instance rather than making one per request.

| Option | Type | Default | |
| --- | --- | --- | --- |
| `storage` | `{ getItem, setItem }` | in memory | [Caching](/docs/caching) |
| `throwOnError` | `boolean` | `false` | see below |
| `apiBase` | `string \| false` | the hosted proxy in a browser, otherwise unset | [Browser and web containers](/docs/browser) |

By default a provider that fails to start, or throws from any of the three methods, is logged and skipped. Set `throwOnError` and you get the error instead.

## `resolveFont()`

```ts
resolveFont(
  family: string,
  options?: Partial<ResolveFontOptions>,
  providers?: string[]
): Promise<ResolveFontResult & { provider?: string }>
```

You get back `fonts`, the `@font-face` descriptors; `fallbacks`, the [generic families](https://developer.mozilla.org/en-US/docs/Web/CSS/Reference/Properties/font-family#generic-name) to put after yours in a stack; and the `provider` that answered.

Options are hints. Ask a provider that only serves woff2 for `otf` and you'll get woff2.

| Option | Type | Default |
| --- | --- | --- |
| `weights` | `string[]` | `['400']` |
| `styles` | `('normal' \| 'italic' \| 'oblique')[]` | `['normal', 'italic']` |
| `subsets` | `string[]` | `['cyrillic-ext', 'cyrillic', 'greek-ext', 'greek', 'vietnamese', 'latin-ext', 'latin']` |
| `formats` | `('woff2' \| 'woff' \| 'otf' \| 'ttf' \| 'eot')[]` | `['woff2']` |
| `options` | `{ [provider: string]: Record<string, unknown> }` | none |

A weight range is one string with a space in it: `'100 900'`. The defaults above are exported as `defaultResolveOptions`.

[Resolving fonts](/docs/resolving) explains what each option does to the answer. What goes in `options` is up to each provider, and the built-in ones are under [Providers](/docs/providers).

## `listFonts()`

```ts
listFonts(providers?: string[]): Promise<string[] | undefined>
```

Every family name the providers will list, or `undefined` if none of them can. `npm` and `adobe` never list.

## `getFontProperties()`

```ts
getFontProperties(
  family: string,
  providers?: string[]
): Promise<(FontProperties & { provider?: string }) | undefined>
```

What a family publishes, from the first provider that knows it, and `undefined` when none of them do.

Two things to watch when you read the result. `weights` mixes discrete values (`'400'`) with variable ranges (`'100 900'`). And a missing field means the provider doesn't publish that information, not that there's nothing to publish: `formats` in particular is what the provider can serve in general, so a format listed there may still be missing for the family you asked about.

## Asking only some providers

All three methods take a list of provider names as their last argument. The default is every provider the instance was built with.

```ts
const unifont = await createUnifont([providers.google(), providers.bunny()])

await unifont.resolveFont('Poppins', {}, ['bunny'])
await unifont.getFontProperties('Poppins', ['bunny'])
await unifont.listFonts(['bunny'])
```

## `FontFaceData`

```ts
interface FontFaceData {
  src: Array<{ name: string } | { url: string, format?: string, tech?: string }>
  display?: 'auto' | 'block' | 'swap' | 'fallback' | 'optional'
  weight?: string | number | [number, number]
  stretch?: string
  style?: string
  unicodeRange?: string[]
  featureSettings?: string
  variationSettings?: string
  metrics?: FontMetrics
  meta?: { priority?: number, subset?: string, init?: RequestInit }
}
```

A `src` entry with `name` is a local font, one with `url` is remote. `meta.subset` is the provider's own name for the range. `meta.init` holds a `RequestInit` for the few providers whose files need headers.

## `FontMetrics`

```ts
interface FontMetrics {
  unitsPerEm: number
  ascent?: number
  descent?: number
  lineGap?: number
  capHeight?: number
  xHeight?: number
  xWidthAvg?: number
}
```

Values are in font units, using the same vocabulary as [`@capsizecss/metrics`](https://github.com/seek-oss/capsize), so they can be used to generate fallback metric overrides (`size-adjust`, `ascent-override`, ...) without downloading and parsing the font file.

## `defineFontProvider()`

```ts
function defineFontProvider<Name extends string, Options, FamilyOptions>(
  name: Name,
  provider: (options: Options, ctx: ProviderContext) => Awaitable<{
    resolveFont: (family: string, options: ResolveFontOptions<FamilyOptions>) => Awaitable<ResolveFontResult | undefined>
    getFontProperties?: (family: string) => Awaitable<FontProperties | undefined>
    listFonts?: () => Awaitable<string[] | undefined>
  } | undefined>
): (options?: Options) => Provider<Name, FamilyOptions>
```

`resolveFont()` is the only method you have to write. [Writing a provider](/docs/custom-providers) covers the rest.
