---
id: vanilla/api/format
title: Formatting
---

`@secundus-studio/stift-format` — tree-shakable `Intl` helpers with no state. Import only what you need; each module is standalone. The `useFormatter` hooks wrap these exact functions; vanilla consumers call them directly with the locale passed explicitly.

All `options` objects take `{ locale }` plus the matching `Intl` options; `locale` is required — pass `stift.getLocale()` to stay in sync with the active locale.

## Numbers

- `formatNumber(value, options)` — `options: NumberFormatOptions`.
- `formatCurrency(value, currency, options)` — `currency: RegisteredCurrencies`, narrowed by the typegen to your config list.
- `formatPercent(value, options)` — `options: NumberFormatOptions`.

## Dates

- `formatDate(value, options)` / `formatTime(value, options)` / `formatDateTime(value, options)` — `value: Date | number | string`, `options: DateTimeFormatOptions`.
- `formatRelativeTime(value, unit, options)` — `unit: Intl.RelativeTimeFormatUnit`, `options: { locale, numeric?, style? }`.

## Lists

- `formatList(list, options)` — `list: Iterable<string>`, `options: ListFormatOptions`.

## Units

Values are always in the category base unit; the unit only changes rendering:

- `formatUnit(value, options)` — `options: UnitNumberFormatOptions` with the target `unit` inside.
- `convertUnit(value, from, to): number` — pure conversion between named units.
- `fromBase(value, unit)` / `toBase(value, unit)` — the two halves of a conversion, for custom pipelines.

## Examples

```ts
import { formatCurrency, formatUnit } from '@secundus-studio/stift-format'

formatCurrency(9.99, 'EUR', { locale: stift.getLocale() })          // "€9.99"
formatUnit(12000, { locale: 'en', unit: 'kilometer' })              // "12 km"
```

## Next

- Choosing units → [`useUnits`](../../react/api/use-units.md)
- Unit state without React → [Translating & Formatting](../translating.md)
- Rendering with hooks → [`useFormatter`](../../react/api/use-formatter.md)
