pofile-tspofile-ts

Format Styles

Built-in and custom format styles for numbers, dates, times, and lists

pofile-ts extends ICU MessageFormat with 50+ built-in format styles and supports custom styles for full control over formatting. All styles use native Intl APIs — zero additional bundle size, full localization support.

Quick Reference

How It Works

ICU MessageFormat uses the syntax {variable, type, style}:

import { compileIcu } from "pofile-ts"

// Basic: {variable, type}
compileIcu("{n, number}", { locale: "en" })({ n: 1234.5 })
// → "1,234.5"

// With style: {variable, type, style}
compileIcu("{n, number, compact}", { locale: "en" })({ n: 1500 })
// → "1.5K"

Types available: number, date, time, list, plural, select, duration, ago, name

Wie es funktioniert

ICU MessageFormat nutzt die Syntax {variable, typ, stil}:

import { compileIcu } from "pofile-ts"

// Einfach: {variable, typ}
compileIcu("{n, number}", { locale: "de" })({ n: 1234.5 })
// → "1.234,5"

// Mit Stil: {variable, typ, stil}
compileIcu("{n, number, compact}", { locale: "de" })({ n: 1500 })
// → "1500" (oder "1,5 Tsd." je nach Browser)

Verfügbare Typen: number, date, time, list, plural, select, duration, ago, name

Cómo funciona

ICU MessageFormat usa la sintaxis {variable, tipo, estilo}:

import { compileIcu } from "pofile-ts"

// Básico: {variable, tipo}
compileIcu("{n, number}", { locale: "es" })({ n: 1234.5 })
// → "1.234,5"

// Con estilo: {variable, tipo, estilo}
compileIcu("{n, number, compact}", { locale: "es" })({ n: 1500 })
// → "1,5 mil"

Tipos disponibles: number, date, time, list, plural, select, duration, ago, name


Number Styles

Standard ICU Styles

These are part of the ICU MessageFormat specification:

StyleDescriptionExample (en)
(default)Locale-aware decimal1,234.5
integerNo decimal places1,235
percentPercentage42%
currencyDynamic currency from values.currency$99.99
compileIcu("{rate, number, percent}", { locale: "en" })({ rate: 0.42 })
// → "42%"

compileIcu("{price, number, currency}", { locale: "en" })({ price: 99.99, currency: "EUR" })
// → "€99.99"

Built-in Extended Styles (pofile-ts)

Compact Notation

Perfect for dashboards, social media counts, and anywhere space is limited:

StyleDescriptionExample
compactShort form (K, M, B)1.5K, 2.5M
compactLongLong form1.5 thousand, 2.5 million
compileIcu("{followers, number, compact}", { locale: "en" })({ followers: 2500000 })
// → "2.5M"

compileIcu("{views, number, compactLong}", { locale: "en" })({ views: 1500 })
// → "1.5 thousand"

Precision Control

StyleDescriptionExample
decimal11 decimal place3.1
decimal22 decimal places3.14
decimal33 decimal places3.142
noGroupingNo thousand separators1000000
compileIcu("{price, number, decimal2}", { locale: "en" })({ price: 19.9 })
// → "19.90"

Sign Display

StyleDescriptionExample
signAlwaysAlways show +/-+5, -3
signExceptZeroShow +/- except for 0+5, 0, -3
compileIcu("{change, number, signAlways}", { locale: "en" })({ change: 5 })
// → "+5"

Kompakte Notation

Perfekt für Dashboards, Social-Media-Zahlen und überall wo Platz begrenzt ist:

StilBeschreibungBeispiel
compactKurzform (Tsd., Mio.)1,5 Tsd., 2,5 Mio.
compactLongLangform1,5 Tausend, 2,5 Millionen
compileIcu("{followers, number, compact}", { locale: "de" })({ followers: 2500000 })
// → "2,5 Mio."

compileIcu("{views, number, compactLong}", { locale: "de" })({ views: 1500 })
// → "1,5 Tausend"

Präzisionskontrolle

StilBeschreibungBeispiel
decimal11 Dezimalstelle3,1
decimal22 Dezimalstellen3,14
decimal33 Dezimalstellen3,142
noGroupingKeine Tausendertrennzeichen1000000
compileIcu("{price, number, decimal2}", { locale: "de" })({ price: 19.9 })
// → "19,90"

Vorzeichenanzeige

StilBeschreibungBeispiel
signAlwaysImmer +/- anzeigen+5, -3
signExceptZero+/- außer bei 0+5, 0, -3
compileIcu("{change, number, signAlways}", { locale: "de" })({ change: 5 })
// → "+5"

Notación Compacta

Perfecto para dashboards, redes sociales y cualquier lugar con espacio limitado:

EstiloDescripciónEjemplo
compactForma corta (mil, M)1,5 mil, 2,5 M
compactLongForma larga1,5 mil, 2,5 millones
compileIcu("{followers, number, compact}", { locale: "es" })({ followers: 2500000 })
// → "2,5 M"

compileIcu("{views, number, compactLong}", { locale: "es" })({ views: 1500 })
// → "1,5 mil"

Control de Precisión

EstiloDescripciónEjemplo
decimal11 decimal3,1
decimal22 decimales3,14
decimal33 decimales3,142
noGroupingSin separadores de miles1000000
compileIcu("{price, number, decimal2}", { locale: "es" })({ price: 19.9 })
// → "19,90"

Visualización de Signo

EstiloDescripciónEjemplo
signAlwaysSiempre mostrar +/-+5, -3
signExceptZeroMostrar +/- excepto 0+5, 0, -3
compileIcu("{change, number, signAlways}", { locale: "es" })({ change: 5 })
// → "+5"

Unit Styles (pofile-ts)

StyleExample (en)
byte1,024 B
kilobyte512 kB
megabyte1.5 MB
gigabyte2 GB
terabyte1 TB
compileIcu("File size: {size, number, megabyte}", { locale: "en" })({ size: 1.5 })
// → "File size: 1.5 MB"
StyleExample (en)
meter100 m
kilometer5 km
mile3 mi
compileIcu("Distance: {d, number, kilometer}", { locale: "en" })({ d: 42.195 })
// → "Distance: 42.195 km"
StyleExample (en)
celsius22°C
fahrenheit72°F
compileIcu("Temperature: {temp, number, celsius}", { locale: "en" })({ temp: 22 })
// → "Temperature: 22°C"
StyleExample (en)
kilogram70 kg
gram500 g
pound154 lb
liter1.5 L
milliliter250 mL
compileIcu("Weight: {w, number, kilogram}", { locale: "en" })({ w: 70 })
// → "Weight: 70 kg"
StyleExample (en)
second30 sec
minute5 min
hour2 hr
day3 days
week2 wk
month6 mo
year1 yr
compileIcu("Duration: {t, number, minute}", { locale: "en" })({ t: 45 })
// → "Duration: 45 min"

Date Styles

Standard ICU Styles

StyleExample (en)Example (de)
(default)Dec 15, 202415.12.2024
short12/15/2415.12.24
mediumDec 15, 202415.12.2024
longDecember 15, 202415. Dezember 2024
fullSunday, December 15, 2024Sonntag, 15. Dezember 2024

Built-in Extended Styles (pofile-ts)

StyleDescriptionExample
isoISO-like format12/15/2024
weekdayWeekday onlySunday
weekdayShortShort weekdaySun
monthYearMonth and yearDecember 2024
monthYearShortShort month and yearDec 2024
monthDayMonth and dayDec 15
monthDayLongLong month and dayDecember 15
dayMonthDay and month15 Dec
dayMonthYearDay, month, yearDec 15, 2024
weekdayMonthDayWeekday, month, daySunday, December 15
compileIcu("Published: {d, date, monthYear}", { locale: "en" })({ d: new Date(2024, 11, 15) })
// → "Published: December 2024"

compileIcu("Today is {d, date, weekday}", { locale: "en" })({ d: new Date() })
// → "Today is Monday"
StilBeschreibungBeispiel
isoISO-ähnliches Format15.12.2024
weekdayNur WochentagSonntag
weekdayShortKurzer WochentagSo
monthYearMonat und JahrDezember 2024
monthYearShortKurzer Monat und JahrDez. 2024
monthDayMonat und Tag15. Dez.
monthDayLongLanger Monat und Tag15. Dezember
dayMonthTag und Monat15. Dez.
dayMonthYearTag, Monat, Jahr15. Dez. 2024
weekdayMonthDayWochentag, Monat, TagSonntag, 15. Dezember
compileIcu("Veröffentlicht: {d, date, monthYear}", { locale: "de" })({ d: new Date(2024, 11, 15) })
// → "Veröffentlicht: Dezember 2024"

compileIcu("Heute ist {d, date, weekday}", { locale: "de" })({ d: new Date() })
// → "Heute ist Montag"
EstiloDescripciónEjemplo
isoFormato tipo ISO15/12/2024
weekdaySolo día de la semanadomingo
weekdayShortDía cortodom
monthYearMes y añodiciembre de 2024
monthYearShortMes corto y añodic 2024
monthDayMes y día15 dic
monthDayLongMes largo y día15 de diciembre
dayMonthDía y mes15 dic
dayMonthYearDía, mes, año15 dic 2024
weekdayMonthDayDía semana, mes, díadomingo, 15 de diciembre
compileIcu("Publicado: {d, date, monthYear}", { locale: "es" })({ d: new Date(2024, 11, 15) })
// → "Publicado: diciembre de 2024"

compileIcu("Hoy es {d, date, weekday}", { locale: "es" })({ d: new Date() })
// → "Hoy es lunes"

Time Styles

Standard ICU Styles

StyleExample (en)Example (de)
(default)2:30:00 PM14:30:00
short2:30 PM14:30
medium2:30:00 PM14:30:00
long2:30:00 PM GMT+114:30:00 MEZ
full2:30:00 PM Central European Time14:30:00 Mitteleuropäische Zeit

Built-in Extended Styles (pofile-ts)

StyleDescriptionExample (en)
hourMinuteHH:MM14:30
hourMinute1212-hour format2:30 PM
hourMinute2424-hour format14:30
hourMinuteSecondHH:MM:SS14:30:45
hourMinuteSecond1212-hour with seconds2:30:45 PM
hourMinuteSecond2424-hour with seconds14:30:45
hourHour only2 PM
hour1212-hour2 PM
hour2424-hour14
compileIcu("Meeting at {t, time, hourMinute24}", { locale: "en" })({ t: new Date() })
// → "Meeting at 14:30"

compileIcu("Alarm: {t, time, hour12}", { locale: "en" })({ t: new Date(2024, 0, 1, 7, 0) })
// → "Alarm: 7 AM"

List Styles

Standard ICU Styles

StyleDescriptionExample (en)
(default)Conjunction (and)A, B, and C
conjunctionConjunction (and)A, B, and C
disjunctionDisjunction (or)A, B, or C
unitUnit list (no connector)A, B, C

Built-in Extended Styles (pofile-ts)

StyleDescriptionExample (en)
orAlias for disjunctionA, B, or C
shortShort conjunctionA, B, & C
narrowNarrow (minimal)A, B, C
orShortShort disjunctionA, B, or C
orNarrowNarrow disjunctionA, B, or C
unitShortShort unitA, B, C
unitNarrowNarrow unitA B C
compileIcu("Choose: {options, list, or}", { locale: "en" })({ options: ["red", "blue", "green"] })
// → "Choose: red, blue, or green"

compileIcu("Authors: {names, list}", { locale: "en" })({ names: ["Alice", "Bob", "Charlie"] })
// → "Authors: Alice, Bob, and Charlie"

compileIcu("Tags: {tags, list, narrow}", { locale: "en" })({
  tags: ["react", "typescript", "vite"]
})
// → "Tags: react, typescript, vite"
compileIcu("Wähle: {options, list, or}", { locale: "de" })({ options: ["rot", "blau", "grün"] })
// → "Wähle: rot, blau oder grün"

compileIcu("Autoren: {names, list}", { locale: "de" })({ names: ["Alice", "Bob", "Charlie"] })
// → "Autoren: Alice, Bob und Charlie"

compileIcu("Tags: {tags, list, narrow}", { locale: "de" })({
  tags: ["react", "typescript", "vite"]
})
// → "Tags: react, typescript, vite"
compileIcu("Elige: {options, list, or}", { locale: "es" })({ options: ["rojo", "azul", "verde"] })
// → "Elige: rojo, azul o verde"

compileIcu("Autores: {names, list}", { locale: "es" })({ names: ["Alice", "Bob", "Charlie"] })
// → "Autores: Alice, Bob y Charlie"

compileIcu("Tags: {tags, list, narrow}", { locale: "es" })({
  tags: ["react", "typescript", "vite"]
})
// → "Tags: react, typescript, vite"

Custom Styles

When built-in styles aren't enough, define your own with full Intl API options:

import { compileIcu } from "pofile-ts"

const fn = compileIcu("{amount, number, priceEur}", {
  locale: "en",
  numberStyles: {
    priceEur: {
      style: "currency",
      currency: "EUR",
      minimumFractionDigits: 2
    }
  }
})

fn({ amount: 1234.5 })
// → "€1,234.50"

Available Options

OptionIntl APIExample Options
numberStylesIntl.NumberFormatstyle, currency, notation, minimumFractionDigits, unit, etc.
dateStylesIntl.DateTimeFormatweekday, year, month, day, era, etc.
timeStylesIntl.DateTimeFormathour, minute, second, hour12, timeZone, etc.
listStylesIntl.ListFormattype, style

Complex Example

const compile = createIcuCompiler({
  locale: "en",
  numberStyles: {
    // Scientific notation for large numbers
    scientific: { notation: "scientific" },
    // Accounting format (negative in parentheses)
    accounting: { style: "currency", currency: "USD", currencySign: "accounting" },
    // Speed in km/h
    speed: { style: "unit", unit: "kilometer-per-hour" }
  },
  dateStyles: {
    // Quarter + Year
    quarter: { year: "numeric", month: "long" },
    // Relative date context
    relative: { weekday: "long", month: "short", day: "numeric" }
  }
})
import { compileIcu } from "pofile-ts"

const fn = compileIcu("{amount, number, preisEur}", {
  locale: "de",
  numberStyles: {
    preisEur: {
      style: "currency",
      currency: "EUR",
      minimumFractionDigits: 2
    }
  }
})

fn({ amount: 1234.5 })
// → "1.234,50 €"

Verfügbare Optionen

OptionIntl APIBeispiel-Optionen
numberStylesIntl.NumberFormatstyle, currency, notation, minimumFractionDigits, unit, etc.
dateStylesIntl.DateTimeFormatweekday, year, month, day, era, etc.
timeStylesIntl.DateTimeFormathour, minute, second, hour12, timeZone, etc.
listStylesIntl.ListFormattype, style

Komplexes Beispiel

const compile = createIcuCompiler({
  locale: "de",
  numberStyles: {
    // Wissenschaftliche Notation für große Zahlen
    wissenschaftlich: { notation: "scientific" },
    // Buchhaltungsformat (negativ in Klammern)
    buchhaltung: { style: "currency", currency: "EUR", currencySign: "accounting" },
    // Geschwindigkeit in km/h
    geschwindigkeit: { style: "unit", unit: "kilometer-per-hour" }
  },
  dateStyles: {
    // Quartal + Jahr
    quartal: { year: "numeric", month: "long" },
    // Relativer Datumskontext
    relativ: { weekday: "long", month: "short", day: "numeric" }
  }
})
import { compileIcu } from "pofile-ts"

const fn = compileIcu("{amount, number, precioEur}", {
  locale: "es",
  numberStyles: {
    precioEur: {
      style: "currency",
      currency: "EUR",
      minimumFractionDigits: 2
    }
  }
})

fn({ amount: 1234.5 })
// → "1.234,50 €"

Opciones Disponibles

OpciónIntl APIOpciones de Ejemplo
numberStylesIntl.NumberFormatstyle, currency, notation, minimumFractionDigits, unit, etc.
dateStylesIntl.DateTimeFormatweekday, year, month, day, era, etc.
timeStylesIntl.DateTimeFormathour, minute, second, hour12, timeZone, etc.
listStylesIntl.ListFormattype, style

Ejemplo Complejo

const compile = createIcuCompiler({
  locale: "es",
  numberStyles: {
    // Notación científica para números grandes
    cientifico: { notation: "scientific" },
    // Formato contable (negativo entre paréntesis)
    contable: { style: "currency", currency: "EUR", currencySign: "accounting" },
    // Velocidad en km/h
    velocidad: { style: "unit", unit: "kilometer-per-hour" }
  },
  dateStyles: {
    // Trimestre + Año
    trimestre: { year: "numeric", month: "long" },
    // Contexto de fecha relativa
    relativo: { weekday: "long", month: "short", day: "numeric" }
  }
})

Pre-configured Compiler

For real-world apps, use createIcuCompiler to define styles once and reuse everywhere:

import { createIcuCompiler } from "pofile-ts"

// Define once in your i18n config (e.g., src/i18n/compiler.ts)
export const compile = createIcuCompiler({
  locale: "en",
  numberStyles: {
    bytes: { style: "unit", unit: "byte", unitDisplay: "narrow" },
    filesize: { style: "unit", unit: "kilobyte", unitDisplay: "short" },
    percent2: { style: "percent", minimumFractionDigits: 2 }
  },
  dateStyles: {
    iso: { year: "numeric", month: "2-digit", day: "2-digit" },
    monthYear: { month: "long", year: "numeric" }
  },
  timeStyles: {
    clock: { hour: "2-digit", minute: "2-digit", hour12: false }
  }
})

// Use everywhere in your app
const sizeMsg = compile("{size, number, bytes}")
const dateMsg = compile("{d, date, iso}")
const timeMsg = compile("{t, time, clock}")

sizeMsg({ size: 1024 }) // → "1,024B"
dateMsg({ d: new Date() }) // → "12/16/2024"
timeMsg({ t: new Date() }) // → "14:30"

Benefits:

  • DRY — Styles defined once, no repetition
  • Testable — Inject different configs for tests
  • SSR-safe — No global state, each request can have its own compiler
  • Tree-shakeable — Only included in bundle when used

Dynamic Currency

For apps where currency varies per user or transaction:

compileIcu("{price, number, currency}", { locale: "en" })({
  price: 99.99,
  currency: "EUR" // Read from values at runtime
})
// → "€99.99"

The currency is:

  1. Read from values.currency at runtime
  2. Cached per currency for performance
  3. Falls back to USD if not provided

Style Categories Summary

CategoryTypeStyles
Standard ICUnumberinteger, percent, currency
Standard ICUdate/timeshort, medium, long, full
Standard ICUlistconjunction, disjunction, unit
pofile-ts Built-innumbercompact, compactLong, decimal1-3, signAlways, signExceptZero, noGrouping
pofile-ts Built-innumber (units)byte, kilobyte, megabyte, gigabyte, terabyte, meter, kilometer, mile, celsius, fahrenheit, kilogram, gram, pound, liter, milliliter, second, minute, hour, day, week, month, year
pofile-ts Built-indateiso, weekday, weekdayShort, monthYear, monthYearShort, monthDay, monthDayLong, dayMonth, dayMonthYear, weekdayMonthDay
pofile-ts Built-intimehourMinute, hourMinute12, hourMinute24, hourMinuteSecond, hourMinuteSecond12, hourMinuteSecond24, hour, hour12, hour24
pofile-ts Built-inlistor, short, narrow, orShort, orNarrow, unitShort, unitNarrow
CustomallAny Intl options via numberStyles, dateStyles, timeStyles, listStyles

On this page