Unicode CLDR Pluralization Rules
make-plural provides JavaScript functions that implement the Unicode CLDR pluralization rules for approximately 220 languages. It handles both cardinal (e.g., 'one book') and ordinal (e.g., '1st book') pluralization categories. As of version 8.1.0, the library is actively maintained with regular updates to support the latest CLDR versions, ensuring accuracy for new locales and rule changes. Key differentiators include its pre-compiled, runtime-dependency-free functions, optimized for tree-shaking with ES modules, which can result in very small bundle sizes when only specific locales are imported. It is used internally by the `intl-pluralrules` polyfill and offers companion packages `make-plural-cli` and `make-plural-compiler` for custom build generation. The project maintains a steady release cadence, often tied to new CLDR versions or feature enhancements like compact notation support, ensuring current and accurate pluralization logic.
Common errors
-
TypeError: make_plural__WEBPACK_IMPORTED_MODULE_0__.en is not a function
cause Attempting to use `make-plural` with CommonJS `require()` syntax or an outdated bundler configuration after v8.0.0.fixUpdate your code to use ES module `import { en } from 'make-plural'` syntax and ensure your build system supports ES modules. -
SyntaxError: Unexpected token 'const' or SyntaxError: Unexpected token '=>'
cause Running code generated by `make-plural@7.0.0` or later in an environment that does not support ES6 syntax without proper transpilation.fixConfigure your build process (e.g., Babel) to transpile ES6+ syntax to a compatible target for your deployment environment. -
TypeError: Cannot read properties of undefined (reading 'cardinal')
cause Attempting to access the `pt-PT` locale directly using the hyphenated string as a JavaScript object key from exports like `pluralCategories`.fixUse the transformed identifier `pt_PT` (with an underscore) when accessing the Portuguese (Portugal) locale, e.g., `Categories.pt_PT`. -
My bundle size is unexpectedly large despite only using a few locales.
cause Using wildcard imports (e.g., `import * as Plurals from 'make-plural/plurals'`) instead of named imports, which prevents effective tree-shaking by bundlers.fixRefactor your imports to use named imports for specific locales, e.g., `import { en, fr } from 'make-plural/cardinals'`.
Warnings
- breaking The `make-plural` package dropped CommonJS exports, becoming an ES module-only package. Projects using `require()` will fail.
- breaking The `make-plural` package license changed to the OSI-approved Unicode Data Files and Software License. Additionally, generated functions now use ES6 `const` and `=>` syntax.
- gotcha For optimal bundle size and effective tree-shaking, always use named imports when importing specific locales (e.g., `import { en } from 'make-plural/cardinals'`) instead of wildcard imports (e.g., `import * as Cardinals from 'make-plural/cardinals'`) from sub-paths.
- gotcha The locale code `pt-PT` (Portuguese as spoken in Portugal) is transformed to `pt_PT` for JavaScript identifier compatibility when accessed as an object key (e.g., from `make-plural/pluralCategories`).
- gotcha The `make-plural/ordinals` module provides ordinal pluralization functions but covers a slightly smaller subset of locales compared to the main `make-plural` or `make-plural/cardinals` modules due to limitations in CLDR data availability for ordinal rules.
Install
-
npm install make-plural -
yarn add make-plural -
pnpm add make-plural
Imports
- en
const { en } = require('make-plural')import { en } from 'make-plural' - en
import * as Cardinals from 'make-plural/cardinals'
import { en } from 'make-plural/cardinals' - LocalePluralFunc
import type { LocalePluralFunc } from 'make-plural' - pt_PT
import * as Categories from 'make-plural/pluralCategories'; Categories['pt-PT']
import * as Categories from 'make-plural/pluralCategories'; Categories.pt_PT
Quickstart
import { en, fr } from 'make-plural';
import { en as ordinalEn } from 'make-plural/ordinals';
import * as Categories from 'make-plural/pluralCategories';
// Cardinal pluralization
console.log('English cardinal for 1:', en(1)); // 'one'
console.log('English cardinal for 2:', en(2)); // 'other'
console.log('French cardinal for 1:', fr(1)); // 'one'
console.log('French cardinal for 2:', fr(2)); // 'one'
console.log('French cardinal for 3:', fr(3)); // 'other'
// Ordinal pluralization using the combined function (second argument `true`)
console.log('English ordinal for 1:', en(1, true)); // 'one'
console.log('English ordinal for 2:', en(2, true)); // 'two'
console.log('English ordinal for 3:', en(3, true)); // 'few'
// Ordinal pluralization using the dedicated ordinals module
console.log('English ordinal (dedicated module) for 3:', ordinalEn(3)); // 'few'
// Accessing plural categories for a locale
const enCategories = Categories.en.cardinal;
console.log('English cardinal categories:', enCategories); // ['one', 'other']
const ptPtCategories = Categories.pt_PT.cardinal; // Note: pt-PT becomes pt_PT
console.log('Portuguese (Portugal) cardinal categories:', ptPtCategories); // ['one', 'other']
// Example with string representation of a number
console.log('English cardinal for "1.0":', en('1.0')); // 'other'