# i18next-icu

> i18nFormat plugin to use ICU format with i18next

Latest version **2.4.4** (published 2026-06-30) · MIT license · 0 weekly downloads

## Install

```sh
npm install i18next-icu
pnpm add i18next-icu
yarn add i18next-icu
bun add i18next-icu
```

## Health

**Score 70/100 (B)** — status: active.

Positive: has types; esm support; no vulnerabilities; recently updated; high maintenance score; high quality score.

Warnings: low downloads.

## Facts

| | |
|---|---|
| Version | 2.4.4 |
| Published | 2026-06-30 |
| First published | 2018-04-13 |
| Weekly downloads | 0 |
| License | MIT |
| TypeScript types | bundled |
| Module format | ESM + CommonJS |
| Dependencies | 0 |
| Unpacked size | 743.4 KB |
| Known vulnerabilities | 0 |
| Install scripts | no |
| GitHub stars | 98 |
| Author | Jan Mühlemann |
| Maintainers | adrai, jamuhl |
| Keywords | i18next, i18next-format |

## Links

- npm: https://www.npmjs.com/package/i18next-icu
- Repository: https://github.com/i18next/i18next-icu
- Issues: https://github.com/i18next/i18next-icu/issues
- npm.io page: https://npm.io/package/i18next-icu

## Alternatives

- [mobx-react](https://npm.io/package/mobx-react.md) — 2.8M weekly downloads
- [rc-tree](https://npm.io/package/rc-tree.md) — 2.6M weekly downloads
- [@react-oauth/google](https://npm.io/package/@react-oauth/google.md) — 1.3M weekly downloads
- [@wagmi/connectors](https://npm.io/package/@wagmi/connectors.md) — 877.0K weekly downloads
- [vee-validate](https://npm.io/package/vee-validate.md) — 836.4K weekly downloads

## Recent versions

- 2.4.4 (latest) — 2026-06-30
- 2.4.3 — 2026-01-31
- 2.4.2 — 2026-01-23
- 2.4.1 — 2025-10-10
- 2.4.0 — 2025-08-21
- 2.3.0 — 2023-04-03
- 2.2.0 — 2023-03-31
- 2.1.0 — 2022-12-02
- 2.0.3 — 2021-03-30
- 2.0.2 — 2021-03-01
- 2.0.0 — 2021-02-10
- 1.4.2 — 2020-06-12
- 1.4.1 — 2020-06-11
- 1.4.0 — 2020-06-03
- 1.3.1 — 2020-04-16
- … 17 more at https://npm.io/package/i18next-icu/versions

## README

# Introduction

[![Coveralls](https://img.shields.io/coveralls/i18next/i18next-icu/master.svg?style=flat-square)](https://coveralls.io/github/i18next/i18next-icu)
[![npm version](https://img.shields.io/npm/v/i18next-icu.svg?style=flat-square)](https://www.npmjs.com/package/i18next-icu)

This changes i18n format from i18next json to ICU using [formatjs/intl-messageformat](https://github.com/formatjs/formatjs/tree/main/packages/intl-messageformat)

## Advice

When using this module, only the ICU message format is respected, this means the i18next format interpolation will not work.
So for example instead of `Hy {{name}}!` it is `Hy {name}!`

# Getting started

Source can be loaded via [npm](https://www.npmjs.com/package/i18next-icu) or [downloaded](https://github.com/i18next/i18next-icu/blob/master/i18nextICU.min.js) from this repo.

```
# npm package
$ npm install i18next-icu
# peer dependencies
$ npm install intl-messageformat
```

Wiring up:

```js
import i18next from "i18next";
import ICU from "i18next-icu";

i18next.use(ICU).init(i18nextOptions);
```

- As with all modules you can either pass the constructor function (class) to the i18next.use or a concrete instance.
- If you don't use a module loader it will be added to `window.i18nextICU`

## Backend Options

```js
{
  // per default icu functions are parsed once and cached for subsequent calls
  memoize: true,

  // memoize if not having a lookup and just using the key fallback as value
  memoizeFallback: false,

  // which events should clear the cache, can be set to false or string of events separated by " "
  bindI18n: '',

  // which events on resourceSource should clear the cache, can be set to false or string of events separated by " "
  bindI18nStore: '',

  // Will be run when parser throws an error. Can return any string, which can be used as a fallback, in case of broken translation.
  // If omitted, the default swallows the error and returns the unsubstituted string (res)
  parseErrorHandler: (err, key, res, options) => {},

  // Transform the language code prior to ICU locale parsing, useful for supporting psuedo-locales like en-ZZ
  // If omitted, the default leaves the language code as is
  parseLngForICU: (lng) => lng,

  // Automatically escape HTML special characters in variable values to prevent ICU parsing issues
  // When true, characters like <, >, &, ", ' in variables are escaped to their HTML entities
  // This prevents strings like "user:<" from being truncated or causing parsing errors
  // Default: false (to maintain backward compatibility)
  escapeVariables: false,
}
```

Options can be passed in by setting options.i18nFormat in i18next.init:

```js
import i18next from "i18next";
import ICU from "i18next-icu";

i18next.use(ICU).init({
  i18nFormat: options
});
```

### more complete sample

```js
import i18next from "i18next";
import ICU from "i18next-icu";

i18next.use(ICU).init({
  lng: "en",
  resources: {
    en: {
      translation: {
        key:
          "You have {numPhotos, plural, " +
          "=0 {no photos.}" +
          "=1 {one photo.}" +
          "other {# photos.}}"
      }
    }
  }
});

i18next.t("key", { numPhotos: 1000 }); // -> You have 1,000 photos.
```

## hints

Using i18next-icu - non of the i18next specific stuff will be available. You will have to rely on what intl-messageformat provides by calling the `t` function with needed options.

All extra features build around i18next plurals, interpolation, context do not get applied to messageformat based keys.

## TypeScript

i18next's type-level interpolation extractor looks for the default `{{variable}}` syntax in your translation strings. ICU MessageFormat uses single braces — and nested-brace plurals like `{count, plural, one {{count} row} other {{count} rows}}` confuse the extractor: the first `{{` and the trailing `}}` are matched as a single interpolation, producing a phantom variable name on every `t()` call ([#85](https://github.com/i18next/i18next-icu/issues/85)).

To opt out of the i18next extractor (since `i18next` v26.2.0), set `parseInterpolation: false` in your `CustomTypeOptions`:

```ts
// i18next.d.ts
import 'i18next';

declare module 'i18next' {
  interface CustomTypeOptions {
    parseInterpolation: false;
    defaultNS: 'translation';
    resources: {
      translation: {
        key: 'You have {numPhotos, plural, =0 {no photos.} =1 {one photo.} other {# photos.}}';
      };
    };
  }
}
```

The flag is type-only; runtime interpolation is handled by `intl-messageformat` via the i18next-icu plugin and is not affected.

## Migration guide

### 1.x.x -> 2.0.0

- updated `intl-messageformat` dependency. Adding locales-data is no longer needed.

---

<h3 align="center">Gold Sponsors</h3>

<p align="center">
  <a href="https://www.locize.com/?utm_source=i18next_icu_readme&utm_medium=github&utm_campaign=readme" target="_blank">
    <img src="https://raw.githubusercontent.com/i18next/i18next/master/assets/locize_sponsor_240.gif" width="240px">
  </a>
</p>

---
_Source: https://npm.io/package/i18next-icu · Machine-readable twin of the npm.io package page. Health data is recomputed on every publish._
