mrkeyoor.com_
Sun 20 Sept 14:46 UTC
npmUtilsupdated 20 Sept 2026

i18next review

i18next 26.4.0 is a runtime translation engine that looks up keys in language resources, chooses plural and context forms, interpolates values, formats through Intl, and follows fallback languages. The core does not depend on React; framework bindings, file or HTTP backends, browser detectors, and translation services are separate packages. Version 26.4.0 caches repeated language-hierarchy resolution and clears that cache when fallbackLng changes. Our install found bundled TypeScript declarations and working CommonJS and ESM entry paths.

Verdict

i18next 26.4.0 installed as 1 package in 1.1 seconds, but its complete browser import measured 13.7 KB gzipped in our sandbox before any backend or framework adapter. Install it when one translation model must span several JavaScript environments; choose a narrower formatter for a small or ICU-first catalog.

We installed it

Lab card: what happened when we installed i18nextScreenshot of i18next documentation
Install✓ · 1.1s1 package on disk · 1 MB
ImportESM import works · require() works · CommonJS package with exports map
Browser13.7 KBgzipped (42.8 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns00 critical · 0 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does i18next install cleanly?

Yes. In a fresh container with an empty cache, npm install i18next finished in 1 seconds, leaving 1 package and 1 MB on disk. npm audit reported no known vulnerabilities.

How much does i18next add to a browser bundle?

13.7 KB gzipped (42.8 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does i18next work with both ESM and CommonJS?

Yes. Both import 'i18next' and require('i18next') worked in Node 22 in our run. The package is published as CommonJS with an exports map.

Does i18next include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

i18next or intl-messageformat: which should you use?

intl-messageformat: Use it when ICU MessageFormat is required and only formatting is needed. i18next 26.4.0 installed as 1 package in 1.1 seconds, but its complete browser import measured 13.7 KB gzipped in our sandbox before any backend or framework adapter.

When should you not use i18next?

A small product has a fixed catalog and can pair plain objects with Intl; our full core import was 13.7 KB gzipped before plugins

API stability4/5i18next 26.4.0 preserves init, t, changeLanguage, resource bundles, plugins, and events as its central API. Major releases still require catalog and type work around plural JSON suffixes, selector typing, formatting, and removed settings. The current release changes internal language-hierarchy caching without changing ordinary translation calls, although applications that mutate resolution options need an explicit cache policy.
Docs4/5I18next.com documents initialization, translation lookup, plural forms, context, interpolation, Intl formatting, fallbacks, namespaces, browser and server operation, TypeScript augmentation, and the plugin catalog. The hard part is interaction between settings: detection, fallback loading, separators, missing keys, and backends live on separate pages. Teams should keep one tested base configuration instead of reconstructing it from examples.
Maintenance5/5The unarchived GitHub repository was pushed on August 20, 2026, the same day npm published 26.4.0, and GitHub reports only 2 open issues and pull requests. Release notes identify the language-resolution cache and its invalidation behavior rather than presenting an unexplained version bump. The combination of a current release, recent repository activity, and a small open queue supports a top maintenance score.
Ecosystem5/5npm counted 21,426,100 downloads from August 19 through 25, 2026, and GitHub lists 8,622 stars. React, Vue, browser, filesystem, HTTP, cache, detector, extraction, and translation-service packages share the same resource conventions. That plugin reach is i18next's main practical advantage, though every selected adapter adds another version and configuration surface to maintain.

Use it if

  • Translation resources must behave the same in browsers, Node services, and framework bindings
  • Plural categories, context variants, nested keys, and fallback chains have outgrown plain object access
  • Languages and namespaces should load on demand instead of joining the initial browser bundle
  • The team or translation vendor already uses i18next JSON conventions
Skip it if

Setup reality

We installed i18next 26.4.0 in a clean Node 22 sandbox in 1.1 seconds. The result was 1 package and 1 MB on disk, with 0 known vulnerabilities in npm audit. i18next declares 0 direct dependencies and 1 peer dependency and occupies 588 KB unpacked. The CommonJS package has an exports map; require() and ESM import both worked. TypeScript declarations are bundled.

Our esbuild import measured 42.8 KB minified and 13.7 KB gzipped. Core initialization needs no credentials or configuration file, but init() returns a promise even when resources are embedded. Wait for it before rendering. React users normally disable interpolation escaping because React already escapes text. Catalogs must use the plural suffixes produced by Intl.PluralRules rather than old generic _plural keys.

Runtime loading adds policy and packages. A backend fetches resources, a detector chooses language, and namespaces split catalogs for lazy delivery. supportedLngs prevents arbitrary detected locale codes from causing pointless requests. Decide the authoritative locale, fallback chain, missing-key reporting, and whether any backend may create missing entries. A write-enabled saveMissing setup should be disabled or tightly controlled in production.

Typed key checking requires TypeScript module augmentation for defaultNS and the resource shape. Without it, t() accepts arbitrary strings. Huge inferred resource types can slow an editor, which is where selector mode and its optimize setting help. Version 26.4.0 caches fallback resolution. Changes to other resolution options may require languageUtils.clearCache(), while function fallbacks and per-call arrays or objects bypass that cache.

Patterns

Initialize an embedded catalog initialize-resources

import i18next from 'i18next';
await i18next.init({
  lng: 'en', fallbackLng: 'en',
  resources: { en: { translation: { greeting: 'Hello {{name}}' } } },
});
console.log(i18next.t('greeting', { name: 'Ada' }));

Await init before the first t call; an early lookup can return the untranslated key.

Choose a locale plural form translate-plural

await i18next.init({ lng: 'en', resources: { en: { translation: { item_one: '{{count}} item', item_other: '{{count}} items' } } } });
i18next.t('item', { count: 2 });

count activates plural selection, and other locales can require categories that English never uses.

Fetch one namespace when needed load-namespace

import HttpBackend from 'i18next-http-backend';
await i18next.use(HttpBackend).init({ lng: 'en', backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' } });
await i18next.loadNamespaces('checkout');

The HTTP backend is a separate package, and rendering must wait until the requested namespace is loaded.

Wait for a language switch change-language

i18next.on('languageChanged', lng => { document.documentElement.lang = lng; });
await i18next.changeLanguage('de');

A backend may fetch resources during changeLanguage, so await it before assuming the new catalog is ready.

Limit browser detection to shipped locales detect-supported-language

import LanguageDetector from 'i18next-browser-languagedetector';
await i18next.use(LanguageDetector).init({ supportedLngs: ['en','de','fr'], fallbackLng: 'en' });

The detector is another dependency; supportedLngs stops an arbitrary browser locale from becoming a resource URL.

Format currency with Intl format-currency

i18next.t('total', { amount: 42.5, formatParams: { amount: { style: 'currency', currency: 'EUR' } } });

The translation string must reference the value with the currency formatter, such as {{amount, currency}}.

Declare the resource type type-keys

import 'i18next';
import common from './locales/en/common.json';
declare module 'i18next' { interface CustomTypeOptions { defaultNS: 'common'; resources: { common: typeof common }; strictKeyChecks: true; } }

Keep this declaration inside tsconfig's include set; otherwise t continues accepting arbitrary strings.

Create a translator per request isolate-server-request

import { createInstance } from 'i18next';
const instance = createInstance();
await instance.init({ lng: requestLocale, fallbackLng: 'en', resources });
const t = instance.t.bind(instance);

Do not call changeLanguage on one shared instance while concurrent requests use different locales.

Alternatives

PackageRegistryPick it when
intl-messageformatnpmUse it when ICU MessageFormat is required and only formatting is needed
typesafe-i18nnpmUse it when generated typed translation functions and compile-time checks lead the design
next-intlnpmUse it for Next.js routing, server components, and ICU messages
i18n-jsnpmUse it for a smaller resource store without i18next's plugin system

More utils guides

lru-cache · ajv · type-fest · p-limit · find-up · js-yaml · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.