i18next is the core translation engine used for managing resources and logic across any JavaScript environment. react-i18next provides React-specific bindings like hooks and components that connect your UI to the i18next core. react-intl is part of the FormatJS ecosystem and offers a complete solution for React apps with a strong focus on the ICU message format standard.
When building global applications, choosing the right internationalization library affects everything from code structure to maintenance. i18next, react-i18next, and react-intl are the leading choices in the JavaScript ecosystem, but they serve different roles and follow different design patterns. Let's break down how they handle common engineering tasks.
i18next is the framework-independent core engine.
// i18next: Core initialization
import i18next from 'i18next';
i18next.init({
lng: 'en',
resources: {
en: { translation: { welcome: 'Hello' } }
}
});
react-i18next is the React binding for the i18next core.
i18next instance.useTranslation for easy access.// react-i18next: React binding setup
import { I18nextProvider } from 'react-i18next';
import i18n from './i18n'; // your i18next instance
function App() {
return <I18nextProvider i18n={i18n}>...</I18nextProvider>;
}
react-intl is a complete suite built on the FormatJS ecosystem.
// react-intl: Complete suite setup
import { IntlProvider } from 'react-intl';
function App() {
return <IntlProvider locale="en" messages={messages}>...</IntlProvider>;
}
i18next uses a direct function call on the instance.
i18next.t() anywhere you have access to the instance.// i18next: Direct function call
import i18n from 'i18next';
const text = i18n.t('welcome');
console.log(text); // Output: Hello
react-i18next uses a hook to get the translation function.
useTranslation hook provides t inside components.// react-i18next: Hook usage
import { useTranslation } from 'react-i18next';
function Welcome() {
const { t } = useTranslation();
return <h1>{t('welcome')}</h1>;
}
react-intl uses a hook to get an intl object.
useIntl hook returns an object with formatting methods.formatMessage with an object descriptor.// react-intl: Hook usage
import { useIntl } from 'react-intl';
function Welcome() {
const intl = useIntl();
return <h1>{intl.formatMessage({ id: 'welcome' })}</h1>;
}
i18next handles variables via string interpolation.
t function.// i18next: Variable interpolation
import i18n from 'i18next';
const user = 'Alice';
const text = i18n.t('greeting', { user });
// Key: 'Hello {{user}}'
react-i18next offers the Trans component for complex JSX.
// react-i18next: Trans component
import { Trans } from 'react-i18next';
function Message() {
return <Trans i18nKey="description">Hello <strong>Alice</strong></Trans>;
}
react-intl uses the FormattedMessage component.
// react-intl: FormattedMessage component
import { FormattedMessage } from 'react-intl';
function Message() {
return <FormattedMessage id="description" values={{ user: 'Alice' }} />;
}
i18next requires manual initialization configuration.
init method.// i18next: Manual config
i18next.init({
lng: 'de',
resources: { de: { translation: { key: 'Wert' } } }
});
react-i18next wraps the app with a context provider.
I18nextProvider makes the instance available via context.// react-i18next: Context provider
import { I18nextProvider } from 'react-i18next';
< I18nextProvider i18n={i18n}>
<App />
</ I18nextProvider>
react-intl wraps the app with its own provider.
IntlProvider requires locale and message definitions.// react-intl: Context provider
import { IntlProvider } from 'react-intl';
< IntlProvider locale="de" messages={deMessages}>
<App />
</ IntlProvider>
| Feature | i18next | react-i18next | react-intl |
|---|---|---|---|
| Type | Core Engine | React Binding | Complete Suite |
| Syntax | Custom Interpolation | Custom + JSX | ICU Standard |
| React Hook | N/A | useTranslation | useIntl |
| Component | N/A | Trans | FormattedMessage |
| Ecosystem | Large Plugin Library | Tied to i18next | FormatJS Family |
While they differ in implementation, all three libraries aim to solve the same core problems for developers.
// i18next
i18next.changeLanguage('fr');
// react-i18next
const { i18n } = useTranslation();
i18n.changeLanguage('fr');
// react-intl
// Usually handled by updating IntlProvider props
// i18next
// key: 'item_count_one', 'item_count_other'
t('item_count', { count: 5 });
// react-i18next
t('item_count', { count: 5 });
// react-intl
// ICU syntax: {count, plural, one {item} other {items}}
// i18next: i18next-parser
// react-i18next: i18next-parser
// react-intl: babel-plugin-formatjs
i18next is the foundation — pick this for non-React projects or if you want to build custom bindings. It offers maximum control but requires more setup for React.
react-i18next is the React specialist — choose this for most React apps. It balances flexibility with ease of use and has a massive plugin ecosystem.
react-intl is the standard bearer — select this for enterprise apps needing strict ICU compliance. It reduces debate on syntax but locks you into the FormatJS ecosystem.
Final Thought: All three libraries are mature and maintained. Your choice depends on whether you prioritize ecosystem flexibility (i18next/react-i18next) or standardization (react-intl).
Choose react-i18next if your project is built on React and you want tight integration with the i18next ecosystem. It provides hooks and components that simplify state management and rendering, making it ideal for teams who need flexibility in loading resources or supporting multiple frameworks later. This package is the standard choice for React developers who want powerful interpolation and plugin support.
Choose i18next if you are building a non-React application or need a standalone translation engine to share across different frontend frameworks. It is the core library that powers react-i18next, so select this when you require direct control over initialization without React-specific bindings. This option is best for backend Node.js services or vanilla JavaScript projects that need robust localization support.
Choose react-intl if you prefer strict adherence to the ICU message format and want a solution maintained by the FormatJS team. It is well-suited for large enterprises that prioritize standardization, build-time message extraction, and robust date and number formatting out of the box. Select this if your team values industry standards over custom configuration options.
Master Branch is the newest version using hooks (>= v10).
$ >=v10.0.0
npm i react-i18next
react-native: To use hooks within react-native, you must use react-native v0.59.0 or higher
For the legacy version please use the v9.x.x Branch
$ v9.0.10 (legacy)
npm i react-i18next@legacy
If you don't like to manage your translation files manually or are simply looking for a better management solution, take a look at i18next-locize-backend. The i18next backend plugin for 🌐 Locize ☁️ — built by the same team behind react-i18next, with CDN delivery, AI translation, and no redeploys for copy changes.
The documentation is published on react.i18next.com and PR changes can be supplied here.
The general i18next documentation is published on www.i18next.com and PR changes can be supplied here.
Before: Your react code would have looked something like:
...
<div>Just simple content</div>
<div>
Hello <strong title="this is your name">{name}</strong>, you have {count} unread message(s). <Link to="/msgs">Go to messages</Link>.
</div>
...
After: With the trans component just change it to:
...
<div>{t('simpleContent')}</div>
<Trans i18nKey="userMessagesUnread" count={count}>
Hello <strong title={t('nameTitle')}>{{name}}</strong>, you have {{count}} unread message. <Link to="/msgs">Go to messages</Link>.
</Trans>
...

Want to learn more about how seamless your internationalization and translation process can be?
Source can be loaded via npm or downloaded from this repo.
# npm package
$ npm install react-i18next
window.reactI18nextHere you'll find a simple tutorial on how to best use react-i18next. Some basics of i18next and some cool possibilities on how to optimize your localization workflow.
Thanks goes to these wonderful people (emoji key):
Jan Mühlemann 💻 💡 👀 📖 💬 | Adriano Raiano 💻 💡 👀 📖 💬 | Pedro Durek 💻 💡 👀 💬 | Tiger Abrodi 💻 👀 |
This project follows the all-contributors specification. Contributions of any kind are welcome!
localization as a service - Locize
Needing a translation management? Want to edit your translations with an InContext Editor? Use the original provided to you by the maintainers of i18next!
Now with a Free plan for small projects! Perfect for hobbyists or getting started.

By using Locize you directly support the future of i18next and react-i18next.