# The Best i18n Libraries for Every Framework in 2027

> One i18n library pick per framework for 2027, with versions and npm downloads checked October 2026: React, Next.js, Vue, SvelteKit, Angular, React Native and Django, plus the tools around them.
- **Author**: Mohit Sapat
- **Published**: 2026-10-27
- **URL**: https://www.babelize.co/blogs/best-i18n-libraries-2027

---

<p class="lead">
    If you are starting a project in 2027, or finally adding languages to one you already have, the first decision is the i18n library. This guide picks one for each major framework, with a runner-up, using numbers rather than reputation: the latest version and weekly npm downloads of every library, checked on October 27, 2026. After the libraries, it covers the tools around them that save the most time: extraction, wrapping hardcoded strings, managing translations and testing.
</p>

<h2>Quick Answer</h2>

<p>
    Use <strong>react-i18next</strong> for React, <strong>next-intl</strong> for Next.js App Router, <strong>vue-i18n</strong> (with <strong>@nuxtjs/i18n</strong> on Nuxt) for Vue, <strong>Paraglide JS</strong> for SvelteKit and other Vite apps, <strong>@angular/localize</strong> for Angular, <strong>i18next with expo-localization</strong> for React Native, and Django's built-in <strong>gettext</strong> for Django. All of them are actively maintained, support plurals and interpolation, and keep translations in plain files in your repo. For tooling, use <strong>i18next-cli</strong> instead of the deprecated i18next-parser, the built-in <code>Intl</code> API for numbers and dates, and pseudo-localization for testing.
</p>

<h2>How We Picked</h2>

<ul>
    <li><strong>Maintained.</strong> A release in the last few months, and no deprecation notice. Libraries change with their frameworks; an abandoned one becomes a migration later.</li>
    <li><strong>Correct plurals and formatting.</strong> Languages such as Polish and Arabic have more plural forms than English. The library must handle them, ideally through ICU MessageFormat or <code>Intl.PluralRules</code>.</li>
    <li><strong>Fits the framework's rendering model.</strong> Server Components in Next.js, SSR in Nuxt and SvelteKit, bundled files on mobile.</li>
    <li><strong>Adoption.</strong> Weekly downloads are a rough signal, not a ranking: they show how many answers, examples and plugins you will find when something breaks.</li>
    <li><strong>Plain files.</strong> Translations live in JSON, PO or similar files you own, so you can change tools later.</li>
</ul>

<h2>The Picks at a Glance</h2>

<table>
    <thead>
        <tr>
            <th>Framework</th>
            <th>Pick</th>
            <th>Latest version</th>
            <th>Weekly downloads</th>
            <th>Runner-up</th>
        </tr>
    </thead>
    <tbody>
        <tr><td>React</td><td>react-i18next</td><td>17.1</td><td>12.9M</td><td>Lingui 6, react-intl 12</td></tr>
        <tr><td>Next.js (App Router)</td><td>next-intl</td><td>4.14</td><td>3.9M</td><td>next-i18next 16</td></tr>
        <tr><td>Vue / Nuxt</td><td>vue-i18n / @nuxtjs/i18n</td><td>11.4 / 10.6</td><td>3.2M / 525K</td><td>Paraglide JS</td></tr>
        <tr><td>Svelte / SvelteKit</td><td>Paraglide JS</td><td>2.29</td><td>348K</td><td>svelte-i18n (no release since 2024)</td></tr>
        <tr><td>Angular</td><td>@angular/localize</td><td>22.2</td><td>1.4M</td><td>Transloco, ngx-translate</td></tr>
        <tr><td>React Native / Expo</td><td>i18next + expo-localization</td><td>26.5 / 58.0</td><td>18.5M / 1.4M</td><td>Lingui 6</td></tr>
        <tr><td>Django</td><td>Built-in gettext</td><td>Part of Django</td><td>n/a</td><td>None needed</td></tr>
    </tbody>
</table>

<p>
    Versions and weekly downloads are from the npm registry on October 27, 2026. Downloads count every install, including CI runs and dependencies of other packages (i18next's number includes every react-i18next and next-i18next app), so compare them within a row, not across rows.
</p>

<h2>React: react-i18next</h2>

<p>
    react-i18next is the default for a reason: it has the largest ecosystem of any JavaScript i18n library, the same core runs in React, React Native and Node.js, and plugins cover language detection, lazy loading from a server, and ICU syntax if you want it. Version 17 is current, and i18next itself is on version 26. Our <a href="/blogs/react-i18next-tutorial/">react-i18next tutorial</a> sets it up from scratch.
</p>

<p>
    <strong>Consider Lingui 6</strong> if you prefer writing the English text in your components instead of inventing keys: its <code>&lt;Trans&gt;</code> macro turns <code>&lt;Trans&gt;Welcome back&lt;/Trans&gt;</code> into a message at build time, and its CLI extracts every message into catalogs. Lingui 6 shipped in April 2026 as ESM-only with improved TypeScript support, and it documents React Server Components. <strong>react-intl</strong> (FormatJS, version 12) is the other mature choice, built on ICU MessageFormat throughout.
</p>

<h2>Next.js: next-intl</h2>

<p>
    For the App Router, next-intl is the most direct fit: the same <code>useTranslations</code> API works in Server and Client Components, it handles locale routing in <code>proxy.ts</code> (middleware before Next.js 16), and it uses ICU MessageFormat for plurals and selects. Version 4 is current. The <a href="/blogs/implement-i18n-nextjs-next-intl/">next-intl setup guide</a> walks through it.
</p>

<p>
    <strong>next-i18next is back in the running.</strong> It used to be Pages Router only, but version 16 (March 2026) added App Router support with <code>getT()</code> for Server Components and <code>useT()</code> for Client Components, plus mixed setups where both routers coexist. If your team already knows i18next, or you share translation files with a React Native app, it is now a reasonable choice. <a href="/blogs/next-intl-vs-react-i18next/">next-intl vs react-i18next</a> compares the two approaches in detail.
</p>

<h2>Vue and Nuxt: vue-i18n</h2>

<p>
    vue-i18n is the standard for Vue 3, on version 11. Use the Composition API (<code>useI18n</code>) rather than the legacy API for new projects. On Nuxt, add <strong>@nuxtjs/i18n</strong> (version 10), which wraps vue-i18n and adds localized routes, SEO tags and lazy-loaded locale files. Our <a href="/blogs/vue-i18n-best-practices/">vue-i18n best practices</a> covers the patterns that keep a growing app manageable.
</p>

<h2>Svelte and SvelteKit: Paraglide JS</h2>

<p>
    Paraglide JS is SvelteKit's official i18n integration (<code>npx sv add paraglide</code>). It is a compiler: each message becomes a typed function such as <code>m.greeting({ name })</code>, so typos fail at build time and unused messages are tree-shaken out of the bundle. Version 2 also works with React, TanStack Start, Vue, Solid, Astro and plain Vite apps, which makes it the best framework-agnostic pick here.
</p>

<p>
    svelte-i18n, the older option, still gets about 90,000 weekly downloads, but its last release was in October 2024. For a new SvelteKit project, start with Paraglide.
</p>

<h2>Angular: @angular/localize</h2>

<p>
    Angular's built-in i18n marks text with the <code>i18n</code> attribute and <code>$localize</code>, extracts it with <code>ng extract-i18n</code>, and builds one bundle per language at compile time. That gives the fastest runtime and follows Angular's own releases (version 22). The trade-off is that switching language means loading a different build. If you need to switch at runtime without a reload, <strong>Transloco</strong> (version 8) or <strong>ngx-translate</strong> (version 18, the most downloaded Angular option) load translations as JSON at runtime instead.
</p>

<h2>React Native and Expo: i18next with expo-localization</h2>

<p>
    On mobile, use the same i18next and react-i18next as on the web, with <code>expo-localization</code> (or <code>react-native-localize</code> in bare apps) to read the device's languages. Translations are bundled with the app, so they work offline and on first launch. Make sure <code>Intl.PluralRules</code> is available (Hermes provides it from React Native 0.73), or every count uses the English plural form. Our <a href="/blogs/react-native-i18n-expo-i18next/">React Native i18n guide</a> covers bundling, plurals, right-to-left layouts and translating the app name.
</p>

<h2>Django: Built-In gettext</h2>

<p>
    Django needs no extra library. Mark strings with <code>gettext</code> or <code>{% translate %}</code>, run <code>makemessages</code> to produce <code>.po</code> files, translate them and run <code>compilemessages</code>. Plurals, contexts and lazy translation in models are all built in. The <a href="/blogs/django-i18n-gettext-guide/">Django i18n guide</a> covers the full workflow.
</p>

<h2>The Tools Around the Library</h2>

<p>
    The library renders translations. Most of the time in a localization project goes into everything else:
</p>

<ul>
    <li><strong>Extracting keys: i18next-cli.</strong> i18next-parser is deprecated; its README says it is no longer maintained as of September 2025 and points to <a href="https://github.com/i18next/i18next-cli" target="_blank" rel="noopener noreferrer">i18next-cli</a>, which extracts keys, finds unused ones, lints for hardcoded strings and generates TypeScript types. <code>npx i18next-cli migrate-config</code> converts an old parser config. Lingui and FormatJS have their own <code>extract</code> commands.</li>
    <li><strong>Formatting: the <code>Intl</code> API.</strong> Dates, numbers, currencies, relative times and lists are built into every browser and Node.js. You rarely need a formatting library on top. See <a href="/blogs/javascript-intl-api-dates-numbers-currencies/">the JavaScript Intl API guide</a>.</li>
    <li><strong>Testing: pseudo-localization.</strong> Replace every string with a longer, accented version (<code>[Ŵéļçöɱé ƀåçķ]</code>) to find hardcoded text and layouts that break with longer languages, before any real translation exists. See <a href="/blogs/pseudo-localization-testing-guide/">pseudo-localization testing</a>.</li>
    <li><strong>Managing translations: a TMS, if you need one.</strong> Once human translators or reviewers are involved, a translation management system such as Crowdin, Tolgee, Locize or Weblate syncs their work with your repo. Our <a href="/blogs/lokalise-crowdin-alternatives-for-developers/">Lokalise and Crowdin alternatives</a> post compares them with prices.</li>
</ul>

<h2>If Your Strings Are Still Hardcoded</h2>

<p>
    Picking a library is the easy part when the app already has hundreds of components with text like <code>&lt;h1&gt;Welcome back&lt;/h1&gt;</code>. Someone has to find each string, invent a key, replace it with <code>t()</code>, and write the locale files. Two tools automate that first pass:
</p>

<ul>
    <li><strong>i18next-cli</strong> (free, MIT) has an <code>instrument</code> command that wraps hardcoded strings in i18next calls, and a <code>localize</code> command that also extracts the keys and translates them through Locize, the i18next team's paid service. Its README calls <code>instrument</code> a heuristic first pass that will not catch every case, so review the result.</li>
    <li><strong><a href="/">Babelize</a></strong> (our product) does the same pass for React, Next.js App Router, Django and static HTML, with Vue and React Native in beta. It writes react-i18next, next-intl or gettext code, creates the locale files, translates them with your own LLM key or Babelize credits, and leaves the result for you to review with <code>git diff</code> (or opens a pull request from the web app). Later runs translate only new or changed strings.</li>
</ul>

<pre><code>npx babelize translate --to de,fr,ja
git diff</code></pre>

<p>
    To be fair about the limits: Babelize writes JSON and gettext <code>.po</code> files only, does not support Angular or SvelteKit yet, and has no translator workspace, so a TMS is still the right tool if you work with human translators.
</p>

<p>
    Starting a new app instead? The Babelize SDK skips keys entirely: you write <code>babelize("Welcome back")</code> and a build plugin translates it. See <a href="/blogs/i18n-without-translation-keys-babelize-sdk/">i18n without translation keys</a>.
</p>

<h2>What's Changing in 2027</h2>

<ul>
    <li><strong>ESM-only packages.</strong> Lingui 6 dropped CommonJS. Expect more libraries to follow; older Jest setups and CommonJS build scripts are where this breaks.</li>
    <li><strong>Compile-time i18n.</strong> Paraglide compiles messages into tree-shakable functions, and Lingui's macros and Angular's per-locale builds also move work to build time. The benefit is type safety and smaller bundles.</li>
    <li><strong>MessageFormat 2.</strong> Unicode's MessageFormat 2.0 is now a stable part of CLDR and is the successor to the ICU syntax most libraries use. The native <code>Intl.MessageFormat</code> proposal is still at TC39 stage 1, so there is nothing to migrate yet, but the i18next tooling already supports it (i18next-cli can extract and type-check MF2 messages). Keeping messages in ICU today is the easiest path to MF2 later; our <a href="/blogs/icu-messageformat-plurals-guide/">ICU MessageFormat guide</a> covers the syntax.</li>
    <li><strong>AI translation in the toolchain.</strong> CLIs from i18next, Babelize and others now translate locale files directly, so translation can run in the same pull request as the code change. Check that placeholders and plural forms survive; <a href="/blogs/translate-json-files-i18n/">how to translate JSON files without breaking them</a> lists what to check.</li>
</ul>

<h2>How to Choose</h2>

<ul>
    <li><strong>New Next.js App Router project:</strong> next-intl.</li>
    <li><strong>React, React Native, or both sharing translations:</strong> react-i18next.</li>
    <li><strong>You want to write text in components, not keys:</strong> Lingui.</li>
    <li><strong>SvelteKit, or you want typed, tree-shaken messages anywhere:</strong> Paraglide JS.</li>
    <li><strong>Vue or Nuxt:</strong> vue-i18n, with @nuxtjs/i18n on Nuxt.</li>
    <li><strong>Angular:</strong> @angular/localize, or Transloco if you need runtime switching.</li>
    <li><strong>Django:</strong> the built-in gettext.</li>
</ul>

<p>
    Whichever you pick, follow the <a href="/blogs/localization-checklist-for-developers/">localization checklist for developers</a> before your first release, and use <a href="/blogs/locale-codes-bcp-47-explained/">BCP 47 locale codes</a> such as <code>pt-BR</code> for your file names.
</p>
---
- [All articles](https://www.babelize.co/blogs)