// react-intl (ICU MessageFormat)
<FormattedMessage
id="inbox.count"
defaultMessage="{count, plural, one {# message} other {# messages}}"
values={{ count }}
/>
// react-i18next (keys with plural suffixes)
// en.json: { "inbox_one": "{{count}} message", "inbox_other": "{{count}} messages" }
const { t } = useTranslation();
t("inbox", { count });
Both put translations in message files, give components a hook or component to read them, and handle plurals and formatting. They differ mainly in message format and features around it.
react-intl (FormatJS):
- Uses ICU MessageFormat: plurals,
selectand number or date formatting inside one string. - Built directly on the
IntlAPIs. <FormattedMessage>,useIntl().formatMessage, plus<FormattedNumber>and<FormattedDate>.- Messages have ids, a
defaultMessageand adescription, and a CLI extracts them from code.
i18next with react-i18next:
- Its own format:
{{name}}placeholders, and plurals as separate keys with suffixes (_one,_other,_few), chosen withIntl.PluralRules. An ICU plugin is available. useTranslation()gives atfunction.- A large plugin system: language detection, loading files over HTTP, caching.
- Namespaces split translations into files per feature, which you can load on demand.
- It works outside React too, on Node.js servers and in other frameworks.
How to choose:
- Pick react-intl if your translators or translation system work in ICU, and you want strict standards.
- Pick i18next if you want built-in detection, lazy loading and one library across frontend and backend.
- In Next.js App Router projects,
next-intlis also popular. It uses ICU and works with Server Components.
- Both libraries load message files and give components a hook or component to read them.
- react-intl uses ICU MessageFormat and is built on the
IntlAPIs. - react-intl messages have ids, default messages and descriptions that a CLI extracts.
- i18next uses its own format with plural suffixes like
_oneand_other. - i18next has plugins for detection and lazy loading, and namespaces to split files.
next-intlis a common choice for the Next.js App Router.
Read more