# General Translation Knowledge Base: General Translation vs. i18next, react-intl, and next-intl: which i18n library should you use?
URL: https://generaltranslation.com/en-GB/kb/general-translation-vs-i18n-libraries.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Open-source libraries such as i18next, react-intl, and next-intl don't translate anything. They display translations you supply in a catalogue file for each language, written by you, your translators or a separate service. General Translation's libraries are open source too and do the same job, but General Translation also does the translating, using your code as context.
Category: Internationalisation
Last updated: 2026-10-16
Authors: General Translation Team
Published: 2026-10-16

An internationalisation (i18n) library does two jobs while your app runs: it picks the message for the user&#39;s locale, and it formats plurals, dates and numbers for that locale. Open-source libraries such as i18next, react-intl, next-intl, Lingui and vue-i18n handle both, but none of them translates your content. That work is left to you, before the app runs: getting each string into a catalogue file, by key or by extracting inline messages, getting every catalogue translated, and keeping them all up to date as the UI changes. General Translation&#39;s libraries do the same run-time jobs, but General Translation also does the translating: copy stays inline in your components, and translations are generated as a build step.

## What the established libraries do well

Each of these libraries is mature, free and widely used, and each has a different strength:

* **i18next** is the most downloaded. It runs in any JavaScript environment, and the official `i18next-cli` extracts keys from your code and generates TypeScript types for them.
* **react-intl** (FormatJS) is built on ICU MessageFormat, the standard syntax for plurals and selections. Its docs recommend writing each `defaultMessage` inline with a `description` for translators, then collecting them into a catalogue with `formatjs extract`.
* **next-intl** is built for the Next.js App Router. Its translations work in Server Components, messages used only by Server Components can be kept off the client, and message keys can be type-checked. Its inline-message API, added in version 4.5, is still marked as experimental.
* **Lingui** keeps source text inline with macros such as `<Trans>`, generates message IDs for you and extracts messages into PO catalogues.
* **vue-i18n** is the i18n plugin for Vue 3, with messages in JSON, YAML or `<i18n>` blocks inside single-file components.

All of them store translations in catalogue formats, such as JSON and PO, that translators and translation management systems (TMSs) already work with.

## What they leave to you

None of these libraries translates anything. Translations come from you, your translators, or a separate service, such as Locize from the i18next team or a TMS such as Crowdin. Here&#39;s a small inbox component with react-i18next:

```json title="locales/en/translation.json"
{
  "inbox": {
    "title": "Inbox",
    "unread_one": "You have {{count}} unread message.",
    "unread_other": "You have {{count}} unread messages."
  }
}
```

```tsx title="Inbox.tsx"
import { useTranslation } from 'react-i18next';

export function Inbox({ count }: { count: number }) {
  const { t } = useTranslation();
  return (
    <section>
      <h1>{t('inbox.title')}</h1>
      <p>{t('inbox.unread', { count })}</p>
    </section>
  );
}
```

Every other language then needs its own file, such as `locales/es/translation.json`, written by hand or sent out for translation. Each file also needs its language&#39;s plural forms as separate keys: Japanese uses one, Polish four, and Arabic six (`_zero`, `_one`, `_two`, `_few`, `_many` and `_other`). A string added to the component is missing from every other file until someone adds it, and whoever translates the catalogue sees `inbox.unread_other` and a sentence, not the screen it appears on.

## General Translation does the same, and generates the translations

General Translation&#39;s libraries do the same job as i18next, react-intl and next-intl. They pick the right messages for each locale, apply its plural rules, and format numbers, currencies and dates with [`<Num>`](/docs/react/reference/components/num), [`<Currency>`](/docs/react/reference/components/currency) and [`<DateTime>`](/docs/react/reference/components/datetime). They handle ICU-style variables in [`useGT`](/docs/react/reference/hooks/use-gt) strings, keyed dictionaries through [`useTranslations`](/docs/react/reference/hooks/use-translations) for teams that prefer keys, and, in `gt-next`, a URL for each locale. Then General Translation does what the other libraries don&#39;t: it generates the translations.

Here&#39;s the same inbox with `gt-react`. The copy stays in the component, [`<T>`](/docs/react/reference/components/t) marks the JSX to translate, and [`<Plural>`](/docs/react/reference/components/plural) holds the English forms:

```tsx title="Inbox.tsx"
import { T, Plural, Num } from 'gt-react';

export function Inbox({ count }: { count: number }) {
  return (
    <T>
      <section>
        <h1>Inbox</h1>
        <Plural
          n={count}
          one={<p>You have <Num>{count}</Num> unread message.</p>}
          other={<p>You have <Num>{count}</Num> unread messages.</p>}
        />
      </section>
    </T>
  );
}
```

Running [`npx gt translate`](/docs/cli/reference/commands/translate) before your build sends each [`<T>`](/docs/react/reference/components/t) block, with its element structure, to the General Translation API and writes a translation for every target locale. You write the plural forms English uses, and translation generates the forms each target language needs, such as Polish `few` and `many`. [`<Plural>`](/docs/react/reference/components/plural) then picks a translated branch using the plural rules of the reader&#39;s locale. [`<Num>`](/docs/react/reference/components/num) formats the count for the reader&#39;s locale at render, and a value wrapped in [`<Var>`](/docs/react/reference/components/var) is never sent to the API. When you edit the sentence, the next run translates it again; when you delete the component, its translations go with it.

General Translation&#39;s libraries cover Next.js (`gt-next`), React (`gt-react`), Vue 3 (`gt-vue`) and Node.js (`gt-node`), with experimental libraries for React Native, TanStack Start, and Python&#39;s Flask and FastAPI. They&#39;re MIT-licensed and work without a General Translation account: they load translations from any source, and [`gt generate`](/docs/cli/reference/commands/generate) writes template files for teams that translate by hand. No other i18n library sits underneath `gt-react` or `gt-next`, because ICU message parsing and formatting are handled by General Translation&#39;s own packages. Translations ship as files in your build by default, or can be loaded from General Translation&#39;s CDN.

## How the libraries compare

| Library                                                            | How you write copy                                                                                                       | Translates your content? | Where translations come from                                                                                                   | Plurals                                                                                                                    |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------ | ------------------------ | ------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------- |
| [i18next](/kb/general-translation-vs-i18next) with `react-i18next` | Keys in a JSON file per locale                                                                                           | No                       | You, translators, or a service such as Locize                                                                                  | One key per plural form                                                                                                    |
| [`react-intl`](/kb/general-translation-vs-react-intl) (FormatJS)   | Inline `defaultMessage` text, extracted to a JSON catalogue                                                              | No                       | You, translators, or a TMS                                                                                                     | ICU MessageFormat                                                                                                          |
| `next-intl`                                                        | Keys in a JSON file per locale                                                                                           | No                       | You, translators, or a TMS such as Crowdin                                                                                     | ICU MessageFormat                                                                                                          |
| [Lingui](/kb/general-translation-vs-lingui)                        | Inline macros, extracted to PO catalogues                                                                                | No                       | You, translators, or a TMS such as Crowdin                                                                                     | ICU MessageFormat                                                                                                          |
| [`vue-i18n`](/kb/general-translation-vs-vue-i18n)                  | Keys in message objects per locale                                                                                       | No                       | You, translators, or a TMS                                                                                                     | Forms separated by a vertical bar; version 11 needs a custom rule for languages such as Polish                             |
| General Translation (`gt-react`, `gt-next`, `gt-vue`)              | JSX inside [`<T>`](/docs/react/reference/components/t), or strings through [`useGT`](/docs/react/reference/hooks/use-gt) | Yes                      | Generated by [`npx gt translate`](/docs/cli/reference/commands/translate) with context from your code, or written by your team | [`<Plural>`](/docs/react/reference/components/plural) branches; translation generates the forms each target language needs |

Stick with i18next, react-intl, next-intl, Lingui or vue-i18n if your catalogues and translation process already work, if translators or a TMS expect catalogue files, or if your framework isn&#39;t one that General Translation&#39;s libraries support. Use General Translation&#39;s libraries if you want copy to stay readable in your components, translations generated with the context of your code, and every language kept up to date with each build rather than after a translation round.

## Keep your library, or migrate one route at a time

Switching libraries is optional. The `gt` CLI detects `next-intl` or `i18next` from your `package.json` and translates its JSON files while preserving its message syntax. This supports `react-i18next` and `next-i18next` projects when `i18next` is a direct dependency. Point `gt.config.json` at your catalogues:

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "fr", "ja"],
  "files": {
    "json": {
      "include": ["locales/[locale]/*.json"]
    }
  }
}
```

To give a key the context its text can&#39;t carry, add a companion file such as `locales/en/translation.metadata.json` with a `context` or `maxChars` entry for that key. (See [Keyed metadata](/docs/cli/reference/keyed-metadata) and [Generating translations](/docs/cli/guides/generating-translations).)

To move to [`<T>`](/docs/react/reference/components/t), follow [Migrating i18n libraries](/docs/react/guides/migrating-i18n-libraries). It covers three paths: replace key lookups with inline copy, keep your dictionaries and call [`useTranslations`](/docs/react/reference/hooks/use-translations), or run both libraries side by side while you move one route at a time.

General Translation is trusted by the world&#39;s best developer teams, including those at Cursor, Ramp, Profound, Cognition, Sierra and ClickHouse. To try it in your app, start with the [Next.js Quickstart](/docs/react/nextjs-quickstart), the [React Quickstart](/docs/react/react-quickstart) or the [Vue Quickstart](/docs/vue/quickstart).

## Key takeaways

* i18next, react-intl, next-intl and other open-source i18n libraries don&#39;t translate anything. They render and format translations that you produce and keep up to date yourself.
* General Translation&#39;s libraries do the same rendering and formatting work and are also open source and MIT-licensed, but General Translation handles the translating as well, from copy written inline in [`<T>`](/docs/react/reference/components/t), so there are no keys or catalogues to keep in sync.
* You can keep i18next or next-intl and use the `gt` CLI to translate their JSON files, or migrate one route at a time.

## Related questions

- [Why use General Translation instead of a TMS (Smartling, Lokalise, Phrase, Crowdin, or Transifex)?](https://generaltranslation.com/en-GB/kb/general-translation-vs-tms.mdx): A translation management system (TMS) such as Smartling, Lokalise, Phrase, Crowdin, or Transifex coordinates translators, but engineers still extract strings, send them out, wait for translations, and wire them back into the product. General Translation translates content in your code with its context, ships every language with each release, and runs on open-source libraries with no lock-in.
- [Google Translate alternatives: General Translation vs. Google Translate](https://generaltranslation.com/en-GB/kb/general-translation-vs-google-translate.mdx): Google Translate is a quick way to translate one-off text, but shipping a product in another language also needs each string translated in context, consistent terms, correct variables and plurals, review, and a release process. General Translation understands each string's context in your code and automates the whole localisation workflow, from code to review to every release.
- [i18next alternatives: General Translation vs. i18next](https://generaltranslation.com/en-GB/kb/general-translation-vs-i18next.mdx): Choose General Translation to keep copy inline in React components and generate translations with its JSX structure and product context. You can also keep i18next and use General Translation to translate existing catalogues. i18next supplies message rendering and plural selection; translation generation comes from a separate service.
- [react-intl alternatives: General Translation vs. react-intl](https://generaltranslation.com/en-GB/kb/general-translation-vs-react-intl.mdx): General Translation lets React teams keep ICU message syntax while adding translation generation, shared terminology, and Dashboard review. react-intl supplies formatting and FormatJS catalogue tooling; General Translation produces the translations too.
- [General Translation vs. vue-i18n: which should you use?](https://generaltranslation.com/en-GB/kb/general-translation-vs-vue-i18n.mdx): General Translation lets Vue teams write source copy directly in templates and generate translations with the CLI. Its gt-vue plugin renders that content with locale-aware plural and number formatting. Choose it to remove keyed source-file maintenance; vue-i18n remains a good fit for teams using Nuxt's i18n module and an established catalogue workflow.

## Previous and next questions

- Previous question: [General Translation vs. i18n-tasks: which should you use?](https://generaltranslation.com/en-GB/kb/general-translation-vs-i18n-tasks.mdx)
- Next question: [General Translation vs. Intlayer: which should you use?](https://generaltranslation.com/en-GB/kb/general-translation-vs-intlayer.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/en-GB/kb/sitemap.md) for every article.
