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
}))
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'
}
})
Available backends include:
- i18next-http-backend — load from any HTTP/CDN endpoint
- i18next-locize-backend — direct Locize CDN integration with saveMissing
- i18next-fs-backend — load from filesystem (Node.js)
- i18next-chained-backend — chain multiple backends (e.g., localStorage cache + remote)
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."
}
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."
}
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'
}
})
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)
-
basePathscoping 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
- next-i18next v16 guide — complete setup for App Router and Pages Router
- Next.js App Router i18n guide — detailed App Router tutorial
- i18next vs alternatives — broader comparison
- Locize + next-i18next integration — example repository
Top comments (0)