README.md

@cutticat/i18n

Locale, region, and language utilities for CuttiCat projects — built on the built-in Intl API.

Not a translation framework. This package provides constants, normalization, locale parsing/resolution, conversions, display names, and formatting. Message loading, routing, and framework integration stay in your app.

Table of Contents

Overview

@cutticat/i18n centralizes low-level i18n helpers used across CuttiCat apps:

  • ISO code constants (countryCodes, languageCodes, currencyCodes)
  • Normalization with bundled whitelists (normalizeCountryCode, normalizeLanguageCode, normalizeCurrencyCode, normalizeLocaleTag)
  • Locale parsing and closest-match resolution (parseLocaleTag, getClosestLocale)
  • Language ↔ region conversions and flag emoji (Intl.Locale#maximize, @cutticat/country-code-emoji)
  • Localized display names (Intl.DisplayNames)
  • Currency formatting (formatCurrencyWithSymbol)

API contract

Role Functions On failure
Normalization normalizeCountryCode, normalizeLanguageCode, normalizeCurrencyCode, normalizeLocaleTag undefined
Locale parsing / resolution parseLocaleTag, getClosestLocale undefined
Conversion / flags languageToLikelyRegionCode, countryCodeToMainLanguageCode, *FlagEmoji undefined
Display / formatting get*DisplayName, formatCurrencyWithSymbol undefined
Predicate isLocaleInList false

Callers provide UI fallbacks explicitly, for example:

getRegionDisplayName("DE", { locale: "en" }) ?? "DE"
languageToFlagEmoji("en") ?? "🌐"
getClosestLocale(header, ["en", "ru"]) ?? "en"
normalizeCountryCode(input) ?? input

Installation

pnpm i @cutticat/i18n

Quick Start

import {
  countryCodeToMainLanguageCode,
  formatCurrencyWithSymbol,
  getClosestLocale,
  getLanguageDisplayName,
  getRegionDisplayName,
  languageToFlagEmoji,
  languageToLikelyRegionCode,
  normalizeCountryCode,
  normalizeLocaleTag,
  parseLocaleTag,
} from "@cutticat/i18n"

normalizeCountryCode("us") // "US"
normalizeLocaleTag("EN-us") // "en-US"

parseLocaleTag("en-US") // { language: "en", region: "US" }

languageToLikelyRegionCode("en-US") // "US"
countryCodeToMainLanguageCode("RU") // "ru"

getLanguageDisplayName("ru", { locale: "en" }) // "Russian"
getRegionDisplayName("DE", { locale: "en" }) // "Germany"
formatCurrencyWithSymbol("USD", { locale: "en" }) // "$ (US Dollar)"

languageToFlagEmoji("en-US") // "🇺🇸"

getClosestLocale("EN", ["en", "ru"]) // "en"

API

Constants

  • countryCodes, countryCodeSet — ISO 3166-1 alpha-2
  • languageCodes, languageCodeSet — ISO 639-1
  • currencyCodes, currencyCodeSet — ISO 4217 (ICU supportedValuesOf('currency'))

Normalization

Validates format and membership in bundled lists. Pass a custom codes array/set for app whitelists, or false to skip membership and normalize by format only.

  • normalizeCountryCode(code, codes?) — uppercase alpha-2
  • normalizeLanguageCode(code, codes?) — lowercase alpha-2
  • normalizeCurrencyCode(code, codes?) — uppercase alpha-3
  • normalizeLocaleTag(tag) — canonical BCP 47 via Intl.Locale

Locales

  • parseLocaleTag(tag){ language, region?, script? } or undefined
  • ParsedLocaleTag — parsed fields type
  • isLocaleInList(value, supportedLocales) — exact-match type guard
  • getClosestLocale(locale, supportedLocales) — canonical tag, then language subtag, then region (exact match)

Conversions and flags

Thin Intl.Locale#maximize wrappers and @cutticat/country-code-emoji re-exports:

  • languageToLikelyRegionCode(language) — e.g. enUS, pt-BRBR
  • countryCodeToMainLanguageCode(code) — e.g. DEde
  • regionCodeToFlagEmoji(code) — ISO alpha-2 → flag emoji
  • flagEmojiToCountryCode(emoji) — reverse lookup (re-export)
  • languageToFlagEmoji(language) — flag for the likely region of a language tag

ICU caveat: inferred regions/flags for language-only tags (en, ru) reflect ICU defaults. Use explicit regional tags (en-GB, pt-BR) when the UI must target a specific country.

Display names

Thin Intl.DisplayNames wrappers — no bundled-list validation; behavior follows ICU.

  • defaultGetDisplayNameOptions{ locale: "en", style: "long" }
  • GetDisplayNameOptions{ locale?, style? }
  • getLanguageDisplayName(language, options?)
  • getRegionDisplayName(code, options?)
  • getScriptDisplayName(script, options?)
  • getCurrencyDisplayName(code, options?)

Formatting

  • formatCurrencyWithSymbol(code, options?) — e.g. $ (US Dollar) (normalizeCurrencyCode + getCurrencyDisplayName + symbol map)

Documentation

Requirements

  • Node.js >= 22
  • Modern ICU/Intl support (language/region/currency/script display names)
Описание
Low-level utilities for locales, languages, and regions in Intl: normalization of ISO codes, BCP 47 parsing, display names, flags, and currency formatting. Not a translation framework.
Конвейеры
1 успешных
0 с ошибкой
Разработчики