A spec-compliant polyfill for Intl.PluralRules fully tested by the official ECMAScript Conformance test suite

npm Version size

ECMA-402 Spec Compliance

This package is fully compliant with the ECMA-402 specification for Intl.PluralRules and is test262-compliant.

✅ Implemented Features

Core Methods

  • select(number) - Returns the plural category for a number ('zero', 'one', 'two', 'few', 'many', 'other')
  • selectRange(start, end) - Returns the plural category for a number range
  • resolvedOptions() - Returns resolved options
  • supportedLocalesOf(locales) - Returns supported locales

Rule Types

  • 'cardinal' (default) - For cardinal numbers (e.g., "1 item", "2 items")
  • 'ordinal' - For ordinal numbers (e.g., "1st", "2nd", "3rd")

Locale Data

  • Supports 700+ locales with accurate LDML plural rules
  • Includes all 6 plural categories per LDML specification
  • Handles complex plural rules (e.g., Arabic has 6 forms, Chinese has 1)

Example Usage

import '@formatjs/intl-pluralrules/polyfill.js'

const pr = new Intl.PluralRules('en')
pr.select(0) // "other"
pr.select(1) // "one"
pr.select(2) // "other"

const prOrdinal = new Intl.PluralRules('en', {type: 'ordinal'})
prOrdinal.select(1) // "one"   (1st)
prOrdinal.select(2) // "two"   (2nd)
prOrdinal.select(3) // "few"   (3rd)
prOrdinal.select(4) // "other" (4th)

// selectRange for ranges
pr.selectRange(1, 5) // "other" (1-5 items)

Installation

npm i @formatjs/intl-pluralrules

Requirements

Usage

Via polyfill-fastly.io

You can use polyfill-fastly.io URL Builder to create a polyfill script tag for Intl.PluralRules. By default the created URL does not come with any locale data. In order to add locale data, append Intl.PluralRules.~locale.<locale> to your list of features. For example:

<!-- Polyfill Intl.PluralRules, its dependencies & `en` locale data -->
<script src="https://polyfill-fastly.io/v3/polyfill.min.js?features=Intl.PluralRules,Intl.PluralRules.~locale.en"></script>

Simple

import '@formatjs/intl-pluralrules/polyfill.js'
import '@formatjs/intl-pluralrules/locale-data/en.js' // locale-data for en

React Native

The polyfill conditional detection code runs very slowly on Android and can slow down your app's startup time by seconds. Since React Native uses Hermes which does not support Intl.PluralRules, import /polyfill-force instead for much better performance:

import '@formatjs/intl-pluralrules/polyfill-force.js' // instead of /polyfill
import '@formatjs/intl-pluralrules/locale-data/en.js'

Dynamic import + capability detection

async function polyfill(locale: string) {
  const unsupportedLocale = shouldPolyfill(locale)
  // This locale is supported
  if (!unsupportedLocale) {
    return
  }
  // Load the polyfill 1st BEFORE loading data
  await import('@formatjs/intl-pluralrules/polyfill-force.js')
  await import(`@formatjs/intl-pluralrules/locale-data/${unsupportedLocale}.js`)
}