DEV Community

Cover image for next-intl vs next-i18next: Choosing the Right i18n Library for Next.js
Adriano Raiano
Adriano Raiano

Posted on • Originally published at locize.com

next-intl vs next-i18next: Choosing the Right i18n Library for Next.js

Next.js developers choosing an i18n solution will likely narrow it down to two libraries: next-intl and next-i18next. Both support the App Router and Server Components. Both are actively maintained. But they take fundamentally different architectural approaches.

This post compares them on the things that matter for a real project: how translations are loaded, how they integrate with your stack, and what workflows they enable.


Architecture at a glance

next-intl next-i18next
Core Standalone library (built on intl-messageformat) Built on i18next — the most widely used JavaScript i18n framework — with react-i18next
Message format ICU MessageFormat i18next JSON format (the most common format in the JS ecosystem)
App Router Supported Supported via getT() / useT()
Pages Router Limited/legacy Full support via next-i18next/pages
Server Components Supported Supported
Translation loading Custom async loader function (you build it) Backend plugin ecosystem (drop-in packages for CDN, filesystem, Locize, chained caching)
Bundle size Minimal runtime via ICU precompilation Flexible — tree-shakeable, scales with features used
Type safety Build-time catalog extraction Full TypeScript support with selector API

How translations are loaded

This is the most important architectural difference.

next-intl: custom loader function

next-intl uses a request-scoped configuration function (i18n/request.ts) where you define how to load messages:

// i18n/request.ts
import { getRequestConfig } from 'next-intl/server'

export default getRequestConfig(async ({ locale }) => ({
  messages: (await import(`../../messages/${locale}.json`)).default
}))
Enter fullscreen mode Exit fullscreen mode

You can load from local files, a CDN, a CMS, or any async source. There is no plugin system — you write the loader yourself. This is flexible but means every integration is custom code.

next-i18next: backend plugin ecosystem

next-i18next inherits the full i18next backend plugin ecosystem:

import i18next from 'i18next'
import Backend from 'i18next-locize-backend'

i18next.use(Backend).init({
  backend: {
    projectId: 'YOUR_PROJECT_ID'
  }
})
Enter fullscreen mode Exit fullscreen mode

Available backends include:

This plugin architecture means integrations with TMS platforms, CDNs, and caching layers are available as drop-in packages rather than custom code.


Message format

next-intl: ICU MessageFormat

{
  "greeting": "Hello, {name}!",
  "items": "You have {count, plural, one {# item} other {# items}} in your cart."
}
Enter fullscreen mode Exit fullscreen mode

ICU MessageFormat is an industry standard supported by many TMS platforms. next-intl includes a precompilation step (icu-minify) that reduces the runtime to under 1KB.

next-i18next: i18next format

{
  "greeting": "Hello, {{name}}!",
  "items_one": "You have {{count}} item in your cart.",
  "items_other": "You have {{count}} items in your cart."
}
Enter fullscreen mode Exit fullscreen mode

i18next uses its own JSON format with {{interpolation}} syntax and key-based pluralization (suffix _one, _other, _few, etc.). This format is natively understood by Locize and other i18next-compatible tools. It is also widely adopted — i18next is the most downloaded i18n library in the JavaScript ecosystem.

Both formats handle plurals, interpolation, and nesting. The choice is largely about ecosystem compatibility.


saveMissing: automatic key discovery

next-i18next supports i18next's saveMissing feature. When your app encounters a translation key that doesn't exist yet, it can automatically report it to your TMS:

i18next.init({
  saveMissing: true,
  backend: {
    projectId: 'YOUR_PROJECT_ID',
    apiKey: 'YOUR_API_KEY'
  }
})
Enter fullscreen mode Exit fullscreen mode

With the Locize backend, missing keys are batched and sent automatically. Combined with automatic translation, this creates a fully automated pipeline: write code → keys appear in Locize → AI translates → live on CDN.

next-intl does not support saveMissing. Key management is manual — you add keys to your JSON files or TMS yourself.


Translation management integration

next-i18next integrates directly with Locize via the dedicated i18next-locize-backend plugin. This provides:

  • CDN delivery at runtime (translations update without redeploy)
  • saveMissing (automatic key discovery)
  • InContext editor (translate on your running app)
  • Branches (translation CI/CD)
  • Multi-tenancy (per-tenant overrides)

The Locize backend is maintained by the same team that wrote i18next and next-i18next.

next-intl does not have a dedicated TMS plugin. You can integrate with any TMS by writing a custom loader in i18n/request.ts, but the integration is your responsibility. next-intl's documentation mentions Crowdin as a compatible TMS.


Routing and middleware

Both libraries handle locale routing via Next.js middleware:

next-intl uses createNavigation() and next-intl/middleware:

  • URL-based routing with dynamic [locale] segments
  • Domain-based routing supported
  • Built-in locale detection (URL, cookies, Accept-Language)

next-i18next (v16+) uses createProxy() (Next.js 16+) or createMiddleware():

  • Cookie-based locale detection
  • Mixed Router support (App Router + Pages Router coexisting)
  • basePath scoping for multi-router setups

Both approaches work well. The routing mechanism is rarely the deciding factor.


When to choose next-intl

  • You prefer ICU MessageFormat and want it built into the framework
  • You want a standalone, self-contained library with no external dependencies
  • You prefer to write custom loader functions for translation sources
  • You are building a Next.js-only project with no need to share i18n setup across other platforms

When to choose next-i18next

  • You want access to the largest i18n plugin ecosystem — drop-in backends for CDN, filesystem, caching, and managed services
  • You want saveMissing — automatic key discovery from your running app, no manual extraction needed
  • You want CDN delivery — translations that update without redeploying your app
  • You want a managed translation backend with AI translation, review workflows, and a translator UI via Locize
  • You need branches and multi-tenancy for complex localization workflows
  • You want to share the same i18n setup across React, Vue, Node.js, React Native, or other platforms in your stack
  • You want the proven maturity of i18next — 15+ years, most downloaded i18n library in JavaScript

Summary

Both next-intl and next-i18next are production-ready libraries for Next.js internationalization. The choice comes down to what you need beyond basic translation:

  • next-intl is a self-contained solution with ICU message format. Good for Next.js-only projects where you want to manage everything yourself.
  • next-i18next connects you to the i18next ecosystem — the most widely adopted i18n infrastructure in JavaScript. Backend plugins, saveMissing, CDN delivery, AI-powered translation, and a managed backend via Locize are all available as drop-in additions, not custom code you write and maintain.

For teams that want their translations to work across multiple platforms, update without redeploying, and scale with managed infrastructure — next-i18next with Locize is the most complete setup available.


Further reading

Top comments (0)