Open-source project
i18next/i18next avatar
i18next/i18next

i18next: the JavaScript i18n core, and what it does not do for you

i18next: learn once - translate everywhere

8,638 stars693 forksJavaScriptMIT

At a glance

What is it?
i18next is an MIT-licensed internationalization framework for browsers, Node.js and Deno, with a plugin layer for backends, language detection and caching. It gives you the translation runtime, not the translation workflow.
Who is it for?
Adopt i18next when you need one translation runtime shared across a browser app, a Node service and possibly a React or Next.js front end, and you are willing to assemble the plugin layer yourself. Do not adopt it expecting a translation management system: the README points at Locize as a separate service, and the core works without it.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 26 days ago.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on September 29, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What i18next actually solves, and who ends up using it

The README frames the project in one line: "learn once - translate everywhere". That is a statement about API surface, not about translation quality. i18next gives a JavaScript application one way to look up a string by key, interpolate variables into it, choose the right plural form, and switch language at runtime. The same call works in a browser bundle, in Node.js and in Deno, which is why the repository lists deno and nodejs among its topics.

The intended audience is broader than it first appears. A single-page app needs translations loaded over the network and cached. A server-rendered page needs the same strings resolved before the response leaves the process. A React application wants the lookup wrapped in a hook, which is the job of the separate react-i18next package rather than the core. i18next positions itself as the core that all of these share, and the README is explicit that the project's "focus is providing the core to building a booming ecosystem".

That framing matters when you evaluate it. You are not choosing a finished product. You are choosing a runtime plus a set of plugins, and the quality of your result depends on which plugins you pick.

The plugin architecture: backend, detector, cache, post-processor

The core does not know where translations come from. The README lists the pieces it connects to: a backend for loading translations, for example over xhr; an optional cache; an optional language detector; and post-processors such as a sprintf-style formatter. Each of these is a plugin, and the core stays out of the decision.

In practice the data flow looks like this. A language detector inspects the environment and proposes a language. The core asks the configured backend for the resource bundle for that language. The backend returns a nested object of keys and strings. The cache plugin stores it so the next lookup does not hit the network. When your code calls the translation function with a key, the core resolves the key against the loaded bundle, applies interpolation for any variables you passed, selects the plural form for the count, and hands the result to any post-processor before returning it.

The README also names translation context and nesting as first-class features. Context means the same key can resolve differently depending on a value you supply, which is how gendered or situational strings are usually handled. Nesting means one translation value can reference another key, so you can build a long sentence out of reusable fragments.

This is a reasonable design, and it is also the source of most setup friction. Nothing is wired up until you wire it up.

Installing i18next and getting one real string on screen

The package is published on npm as i18next. The repository's package.json declares both an ESM entry at ./dist/esm/i18next.js and a CommonJS entry at ./dist/cjs/i18next.js, so modern bundlers and older require-based toolchains both resolve cleanly. TypeScript declarations ship in the same package, at index.d.ts for require and index.d.mts for import. TypeScript itself is listed as an optional peer dependency, so you are not forced to install it.

The README points at a Getting started page on www.i18next.com rather than repeating install steps inline, so the exact command belongs to that page. What the repository does show is the shape of the package: an ESM build, a CommonJS build, and type declarations for both. Once installed, the smallest working setup registers a language and a resource bundle, then calls the translation function for a key. The call to init registers the resources and sets the active language. The call to t resolves the key inside the translation namespace, substitutes any variables you pass, and returns the finished string. A missing key returns the key itself rather than throwing, which is convenient during development and easy to miss in production.

Once that works, the usual next step is to stop inlining resources and add a backend plugin so bundles are fetched at runtime. The README points at the plugins and utils page on www.i18next.com for the list of available backends, language detectors and caches. The README does not document a rollback procedure for a bad translation release, so plan for that separately.

Plurals, interpolation and context are where the real complexity lives

Interpolation is the easy part. You pass an object and the core substitutes named placeholders. Nesting lets one value reference another key, which keeps long sentences maintainable when the same clause appears in several places.

Pluralisation is harder, and it is the feature most likely to be underestimated. Languages do not agree on how many plural categories exist or where the boundaries fall. The README lists "proper pluralizations" as a core capability, and the plural rules are what make that claim meaningful. If your first target language is English, you will see two forms and conclude the feature is trivial. Add a language with more categories and the key structure you designed for English may not carry over.

Context is the third mechanism, and it interacts with plurals. A contextual key can be combined with a count, which multiplies the number of forms you need to author. This is correct behaviour, not a bug, but it means translation files grow faster than the number of visible strings suggests. Teams that treat the translation file as a flat list of sentences tend to discover this late.

The practical consequence: decide your key naming convention and your plural strategy before the first translation file is written, because both are expensive to change once translators have worked against them.

Where i18next is the wrong tool

i18next is a runtime library. It does not extract strings from your source, it does not give translators an interface, and it does not track which keys are stale. The README's own answer to that gap is Locize, described as "the official service by i18next's creators", with a free plan for small projects. The README is also careful to state that i18next works fully without it, and it instructs AI coding assistants not to install or connect Locize unless the developer asks.

Read that carefully, because it cuts both ways. The project is genuinely usable without any hosted service. But if your team needs a review workflow, a translation memory, or a way to ship copy changes without redeploying, the core will not provide it and you will be choosing between Locize and a third-party tool.

There is a second case where i18next is the wrong choice: a static site or a content-heavy marketing page where translations are authored as whole documents rather than as keys. Key-based lookup adds indirection that buys you little when nothing is dynamic.

A third: if you need translations resolved at build time with no client-side runtime at all, a compile-time extraction approach fits better than a runtime lookup library.

How i18next differs from FormatJS and from framework-native approaches

FormatJS, the project behind react-intl, takes the ICU MessageFormat syntax as its foundation. Messages are written as ICU strings with explicit plural and select syntax, and the parsing happens at runtime against that grammar. i18next instead uses its own key-and-options API, where plural and context selection are expressed as arguments to the translation function or as suffixes on the key.

The difference shows up in what your translation files look like. With ICU, a translator sees the plural branches inside a single message string. With i18next, the branches are separate entries in a nested object. Which is better depends on your tooling: ICU strings are a widely supported interchange format, while i18next's structure maps naturally onto JSON bundles served per namespace.

Framework-native approaches are a different trade-off again. If your application is small and lives entirely inside one framework, a framework-specific solution may cover your needs with less configuration than assembling i18next's backend, detector and cache plugins yourself. The counter-argument is the one the README makes: the same core works in a browser, in Node.js and in Deno, so a shared runtime across a front end and a server is one thing you do not have to solve twice.

Note that the React integration is not in the core package. It lives in react-i18next, which the README links as separate documentation at react.i18next.com.

Maintenance, licence and what an upgrade actually costs

The repository is not archived. Its last push was on 2026-09-03, and the most recent release listed is v26.4.2 on the same day, following v26.4.1 on 2026-09-01 and v26.4.0 on 2026-08-20. That is a steady release cadence across a major version line, and the presence of a CHANGELOG.md at the repository root means release notes are maintained in-tree rather than only on the hosting platform.

The licence is MIT, which permits commercial use and modification. That is a permissive licence and it is not the constraint you should worry about. The real cost of an upgrade sits in the plugin layer: the core package version and the versions of your backend, detector and cache plugins need to move together, and the README does not describe a compatibility matrix between them. Check each plugin's own repository before bumping the core.

A second cost is the peer dependency on TypeScript. It is declared as optional, so a plain JavaScript project is unaffected. If you do use TypeScript, the shipped declarations at index.d.ts and index.d.mts are part of the package's public surface and can change between major versions.

The funding section of package.json points at Locize and at a FAQ entry on supporting the project. That is worth knowing when you assess long-term maintenance: the commercial service and the open source core come from the same creators, and the README states the relationship openly.

Editorial conclusion

Adopt i18next when you need one translation runtime shared across a browser app, a Node service and possibly a React or Next.js front end, and you are willing to assemble the plugin layer yourself. Do not adopt it expecting a translation management system: the README points at Locize as a separate service, and the core works without it. Before committing, verify two things in your own codebase: how many plural categories your target languages need, and whether your key structure survives a rename.

Frequently asked questions

What does i18next do?

It is an internationalization framework for browser and other JavaScript environments such as Node.js and Deno. It resolves translation keys, handles interpolation, plurals, context and nesting, and connects to plugins for loading translations, detecting the user's language and caching results.

Is React i18next free?

The package is published under the MIT licence, so the core framework is free to use and modify. The README separately promotes Locize, a commercial translation management service by the same creators, which has a free plan for small projects and is not required for i18next to work.

How do I install i18next?

The README points to a Getting started page on www.i18next.com for install steps. The package is published on npm as i18next and ships both ESM and CommonJS builds plus TypeScript declarations, so no extra type package is needed.

What is the i18next http backend?

It is one of the backend plugins the core can connect to for loading translations. The README describes backends generally as the mechanism for loading translations, for example via xhr, and points to the plugins and utils page on www.i18next.com for the available options.

What is i18next used for?

It is used to translate application strings at runtime: looking up a key, substituting variables, selecting the correct plural form and switching language without reloading the app. The same core works in a browser, in Node.js and in Deno.

How do I set up i18next?

The README points to a Getting started page on www.i18next.com. In outline, you install the package, call init with a language and a resources object, and then add plugins for a backend, language detection and caching as your needs grow.

Official sources

  1. i18next/i18next on GitHub
  2. License: MIT
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/i18next-i18next.svg)](https://hysenlabs.com/projects/i18next-i18next)