Package detail

locale-matcher

smikhalevski1.1kMIT2.2.1

The super-fast locale matcher and normalizer.

locale, language, intl, bcp47

readme

locale-matcher

The super-fast locale matcher and normalizer in just 1 kB gzipped with zero dependencies.

npm install --save-prod locale-matcher

Usage

Pick the supported locale that best matches the requested locale:

import { pickLocale } from 'locale-matcher';

pickLocale(/* requested locale */ 'en_US', /* supported locales */ ['en-AU', 'en-GB', 'en', 'ru']);
// ⮕ 'en'

pickLocale('hy', ['en-AU', 'en-GB', 'en', 'ru']);
// ⮕ null

Provide a fallback locale if the requested locale isn't supported:

pickLocale('hy', ['en', 'ru'], /* default locale */ 'en');
// ⮕ 'en'

Provide a list of the requested locales to choose from:

pickLocale(['en_US', 'en_AU'], ['en-AU', 'en-GB', 'en', 'ru']);
// ⮕ 'en-AU'

Get the index of the supported locale that best matches the requested one:

import { matchLocale } from 'locale-matcher';

matchLocale('en-US', ['en-AU', 'en-GB', 'en', 'ru']);
// ⮕ 2

matchLocale('hy', ['en-AU', 'en-GB', 'en', 'ru']);
// ⮕ -1

Provide a list of the requested locales:

matchLocale(['en-GB', 'ru-RU'], ['pt', 'en', 'ru']);
// ⮕ 1

Normalize the locale:

import { normalizeLocale } from 'locale-matcher';

normalizeLocale('__EN__US__');
// ⮕ 'en-us'

The lookup algorithm tries to find a locale with the maximum number of matching subtags (e.g., en, US, etc.) and the shortest overall length.

Matching is case-insensitive and ignores non-alpha-ASCII characters so mn-Cyrl-MN is not distinct from MN__cYRL--mn or ++mN__cYrL@Mn++.

Locales are expected start with ISO 639-1, ISO 639-2, ISO 639-3 or ISO 639-5 language code. These codes are interchangeable so chi-CN is not distinct from zh-CN.

locale-matcher doesn't depend on Intl and doesn't throw exceptions if locale is malformed or subtags aren't ordered properly.

Performance

Execution performance is measured in operations per second (± 5%), the higher number is better. Memory consumption (RAM) is measured in bytes, the lower number is better.

Ops/sec RAM
locale-matcher 8,500 kHz 90 B
@formatjs/intl-localematcher 2 kHz 357,000 B

Tests were conducted using TooFast on Apple M1 with Node.js v23.1.0.

To reproduce the performance test suite results, clone this repo and run:

npm ci
npm run build
npm run perf