Faça sua pergunta e obtenha um resumo do documento referenciando esta página e o provedor AI de sua escolha
O conteúdo desta página foi traduzido com uma IA.
Veja a última versão do conteúdo original em inglêsSe você tiver uma ideia para melhorar esta documentação, sinta-se à vontade para contribuir enviando uma pull request no GitHub.
Link do GitHub para a documentaçãoCopiar o Markdown do documento para a área de transferência
Como escolher a biblioteca de i18n certa para React
O React não inclui nenhuma primitiva de i18n. A biblioteca que você escolhe no primeiro dia decide como as traduções são armazenadas, como elas chegam ao bundle e quanto trabalho continuará sendo seu nos próximos anos. A maioria das equipes escolhe pela popularidade e depois descobre os trade-offs quando atinge 2.000 chaves.
Este guia segue o caminho inverso: responda a algumas perguntas sobre o seu projeto primeiro e, em seguida, mapeie as respostas para as bibliotecas mais adequadas. O foco aqui é o React puro (Vite, React Router, TanStack Start). O Next.js tem suas próprias restrições, abordadas na comparação para Next.js.

Índice
Seis perguntas a responder antes de comparar bibliotecas
Uma tabela de recursos é inútil sem saber quais linhas importam para você. Analise estes pontos primeiro.
- Como a aplicação é renderizada? Apenas SPA, SSR com hidratação ou React Server Components. Hooks baseados em context funcionam em qualquer lugar em uma SPA. Com RSC, um hook força
"use client"em todos os componentes que renderizam texto, portanto você também precisará de uma API no lado do servidor. - Quem escreve as traduções? Desenvolvedores, uma equipe interna usando um TMS, uma agência entregando arquivos ICU ou um pipeline de IA. Isso dita o formato do catálogo mais do que qualquer detalhe de API.
- Quantos locales e páginas? Dois locales e cinco páginas podem se dar ao luxo de enviar tudo. Dez locales e cinquenta rotas não podem, e a estratégia de carregamento se torna o custo principal.
- Você precisa de tipos nas chaves? Um erro de digitação em
t("checkout.totl")compila em qualquer biblioteca baseada em chaves, a menos que você mesmo configure os tipos. Decida se isso é aceitável. - O que a string contém? Texto simples, plurais ou frases com um
<Link>no meio. Conteúdo rico é onde a maioria das APIs se torna complicada. - Quanto tempo o projeto vai durar? Um protótipo de três meses e um produto de cinco anos não precisam da mesma quantidade de build tooling.
Anote as respostas. Tudo o que segue faz referência a elas.
O panorama geral em uma imagem
Quinze anos de JavaScript i18n cabem em quatro ondas arquiteturais, e as bibliotecas React que você vai comparar vêm de ondas diferentes.

Catálogos JSON carregados em memória, t("a.b") buscado em runtime, ICU ou uma sintaxe personalizada analisada no navegador. Maiores ecossistemas, runtimes mais pesados, tipos são opcionais (opt-in).
Mensagens extraídas no build, compiladas para catálogos compactos, argumentos tipados. Uma etapa extra de build (extract, compile) em troca de bundles menores.
Projetado em torno de SSR e Server Components. Renderize no servidor, hidrate apenas o que o cliente precisa. Ainda baseado em chaves e centralizado.
O conteúdo é compilado em funções com tree-shaking ou dicionários por componente. Tipos são gerados, traduções ausentes quebram o build e a tradução por IA roda via CLI.
A história do JavaScript i18n detalha como cada onda respondeu aos problemas da anterior.
A decisão que mais importa: onde o conteúdo fica e quando ele carrega
Toda biblioteca de i18n para React tem o mesmo formato: uma store, um provider, um hook. O que o provider recebe acaba no bundle do cliente ou no payload de hidratação. Portanto, as duas escolhas estruturais são:
- Conteúdo centralizado ou com escopo. Um
en.jsonpara a aplicação inteira, ou uma declaração por componente (ou por namespace). - Import estático ou dinâmico. Tudo empacotado na inicialização, ou o locale e a rota ativos buscados sob demanda.
O gráfico abaixo estima o payload para uma aplicação teórica de 1 a 10 páginas, traduzida para 1 a 10 locales, com cerca de 30 KB de texto por página.

Conteúdo centralizado com imports estáticos cresce em ambos os eixos: 10 páginas vezes 10 locales representam 300 KB de texto em cada página. Imports dinâmicos removem o eixo dos locales. O escopo por componente remove o eixo das páginas. Apenas a combinação de ambos mantém o tamanho estável.
Isso não é uma propriedade da biblioteca, é uma propriedade de disciplina. O react-i18next pode ter escopo com namespaces e backends lazy. O use-intl pode ser dividido por rota. Mas nada impõe isso, e um <Button> compartilhado acessando t("common:cta") silenciosamente torna o common uma dependência de todas as rotas. O benchmark mede isso como "vazamento de outras rotas" e "vazamento de outros locales", e é de onde vem a maior parte da diferença entre as bibliotecas.
Se a sua resposta para a pergunta 3 foi "muitos locales, muitas páginas", dê mais peso a esta seção do que a qualquer preferência de API. O artigo sobre i18n por componente vs. centralizado aprofunda o lado da manutenção dessa mesma escolha.
Os candidatos
Os tamanhos das bibliotecas vêm do benchmark no TanStack Start: provider mais hook em um componente vazio, após bundling, tree-shaking e minificação, 10 páginas e 10 locales. O conteúdo é medido separadamente.
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Biblioteca | Onda | Modelo de conteúdo | Tipos nas chaves | Formato de mensagem | Tamanho da biblioteca |
|---|---|---|---|---|---|
react-i18next | Runtime | JSON central, namespaces | Opt-in (CustomTypeOptions) | i18next (sufixos plurais) | ~18.4 kB |
react-intl (FormatJS) | Runtime | JSON central, ICU | Opt-in (extração + union) | ICU | ~15.3 kB |
use-intl | Server-first | JSON central, ICU | Opt-in (declaration merging) | ICU | ~14.1 kB |
@tolgee/react | Runtime | Central, edição em contexto | Não | ICU | ~11.1 kB |
| Lingui | Macro | Texto de origem no código, catálogos compilados | Bom, a partir do compilador | ICU via macros | Pequeno |
| Paraglide | Compilador | Projeto inlang, funções geradas | Gerados | Próprio | Próximo de zero |
| Intlayer | Compilador | .content.ts por componente | Gerados, ativo por padrão | Helpers (plural, enu) | Linha de base |
Os números são um snapshot das versões do benchmark e mudam com novos lançamentos. Execute o benchmark na sua própria aplicação antes de decidir apenas pelo tamanho.
Duas coisas que a tabela não mostra. O Paraglide quase não envia biblioteca porque gera código dentro do seu repositório, o que significa uma etapa de regeneração antes de cada commit e conflitos de merge em arquivos gerados. E o Intlayer requer um plugin de bundler (vite-intlayer ou equivalente), portanto não pode rodar em uma configuração sem build.
Mapeie suas respostas para uma biblioteca
Escolha a solução mais simples que funcione e não invista além do necessário. react-i18next com um único JSON por locale é adequado, e uma década de respostas no Stack Overflow vai economizar seu tempo. Ignore namespaces até precisar deles. Se o protótipo se transformar em um produto, planeje uma migração para conteúdo com escopo; o adaptador de compatibilidade do react-i18next torna isso incremental.
O formato do catálogo já está decidido para você. react-intl é nativo em ICU e as ferramentas de extração do FormatJS foram criadas para esse pipeline. use-intl também lê ICU. react-i18next precisa do plugin ICU e de suas próprias chaves de plural caso contrário. O suporte a ICU no Intlayer ainda é parcial, portanto, se você recebe strings em ICU hoje, trate isso como um impedimento até que o suporte seja concluído.
Prefira conteúdo com escopo e carregamento dinâmico por padrão, e não por convenção. Lingui e Paraglide chegam lá através da compilação. O Intlayer alcança isso por meio de declarações por componente, e o compilador envia apenas o que uma rota renderiza. Com react-i18next ou use-intl, planeje a estratégia de namespaces e lazy-loading no primeiro dia e exija isso em code review, pois as ferramentas não farão isso por você.
Toda biblioteca baseada em chaves pode ser tipada, mas quase nenhuma vem assim por padrão. Se você não quer manter declaration merging que precisa resistir a namespaces carregados dinamicamente, escolha uma biblioteca onde os tipos são gerados a partir do conteúdo: Lingui, Paraglide ou Intlayer. O artigo sobre detecção de traduções ausentes compara o que cada uma detecta em tempo de build.
Nós ricos são onde o t() retornando uma string deixa a desejar. react-i18next e Lingui têm o <Trans>, react-intl tem tags de rich text, todos eles mais trabalhosos do que o caso de string simples. Os nós de conteúdo do Intlayer aceitam JSX, markdown e objetos aninhados diretamente, o que é a melhor escolha se o seu conteúdo vai além de simples rótulos de UI.
Nesse caso, um JSON centralizado não é mais um requisito, já que não há um TMS para importar arquivos. Conteúdo colocalizado junto com uma CLI que preenche locales ausentes é o caminho mais curto. O comando fill do Intlayer roda com sua própria chave de API (OpenAI, Anthropic, Mistral, Gemini) e traduz apenas o que foi alterado. Paraglide e Tolgee oferecem equivalentes hospedados com seus próprios planos.
O React context não cruza a fronteira entre servidor e cliente. Bibliotecas construídas apenas sobre um hook de cliente (react-i18next, react-intl) precisarão de uma API de servidor paralela no dia em que você adotar RSC. use-intl (como next-intl) e Intlayer (como next-intlayer) já possuem essa divisão. Leia o artigo sobre Next.js i18n antes de padronizar um modelo.
Onde cada biblioteca deixa a desejar
Limites honestos, já que todas as opções têm os seus.
react-i18next: a mais pesada do conjunto, formato de plural próprio, tipagem depende da sua própria configuração manual, chaves sem uso acumulam-se silenciosamente.react-intl: DX verbosa (useIntl()e depoisformatMessage({ id })), instância global vinculada a muitos nós.use-intl: simples para começar, difícil de otimizar. Namespaces, carregamento dinâmico e tipagem juntos tornam o desenvolvimento bem mais lento.Lingui: etapa extra de build comextract/compile, várias sintaxes sobrepostas (t(), tagged template,i18n.t(),<Trans>) que confundem desenvolvedores e assistentes de IA.Paraglide: arquivos gerados no repositório, o tree-shaking não surtiu efeito no benchmark React, e o locale é lido do storage a cada nó em vez de vir de uma store.Tolgee: sem tipos nas chaves, onboarding mais difícil, edição em contexto é o principal diferencial.Intlayer: plugin de build obrigatório, ecossistema menor, suporte parcial a ICU, conteúdo distribuído pela codebase por design, logo exportar um único JSON para um tradutor exige ferramentas.gt-react,lingo.dev: não recomendadas no benchmark: erros de cota no build, vendor lock-in e problemas de reatividade que exigiram forçar re-renderizações do provider.
Como cada opção se parece no código
O mesmo componente, um resumo de carrinho com título e plural, escrito com cada candidata. A parte interessante não é o componente em si, mas onde o conteúdo fica e o que o verificador de tipos sabe sobre ele.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
Plurais são chaves com sufixo resolvidas via Intl.PluralRules. t é (key: string) => string a menos que você declare CustomTypeOptions, então t("titel") compila sem erros.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
ICU de ponta a ponta, que é o que a maioria das plataformas de TMS exporta. Tipos em id vêm da etapa de extração do formatjs mais uma union gerada, não prontos de fábrica.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
Mesmo formato do next-intl sem os bindings do Next.js. Chaves são tipadas depois que você estende AppConfig com o tipo das mensagens; dividir namespaces fica por sua conta.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
O idioma de origem fica no componente; outros locales ficam em arquivos .po sob IDs em hash após lingui extract. Esquecer o extract ou compile faz o fallback silencioso para o inglês.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
Cada mensagem é uma função gerada e tipada, portanto uma chave ausente resulta em erro de import. A pasta paraglide/ é gerada dentro do seu repositório e regenerada a cada alteração.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
Todos os locales em um único arquivo ao lado do componente. Os tipos são gerados no build, de modo que title tem autocompletion e um erro de digitação falha no tsc sem necessidade de declaration merging. Excluir a pasta exclui as strings.
Já usa react-i18next, react-intl ou Lingui? Os adaptadores de compatibilidade (react-i18next, react-intl, Lingui) criam aliases para os imports no nível do bundler para que a API existente continue funcionando enquanto você migra componente por componente. O guia de migração cobre o restante.
Antes de tomar sua decisão
Uma tabela de funcionalidades mostra o que uma biblioteca faz hoje. Estes pontos mostram como será a convivência com ela no dia a dia.
Verifique a atividade do repositório.
Commits, tempo de resposta a issues e se a última versão minor foi lançada este ano. Um bom design sem mantenedores é uma migração à espera de acontecer.
Não escolha pelo número de downloads no npm.
A biblioteca mais instalada é a que foi lançada primeiro, não a que melhor se adapta a uma codebase React em 2026. Downloads medem história, não adequação.

Pergunte quem financia o mantenedor e o que eles vendem.
O i18next é apoiado pela Locize. O next-intl / use-intl, vue-i18n, svelte-i18n e Lingui são apoiados pelo Crowdin. Tolgee, Paraglide (inlang) e Intlayer mantêm suas próprias plataformas. Um fornecedor cuja receita depende de traduções hospedadas tem pouco incentivo para tornar a tradução gratuita dentro da sua cadeia de ferramentas. O Intlayer é o único do grupo que oferece tradução por IA via CLI com sua própria chave de API e um CMS que você pode auto-hospedar (self-host).
Está pronto para agentes de IA?
Os agentes ainda têm dificuldades com i18n: esquecem locales, inventam chaves e misturam sintaxes de mensagens. A biblioteca oferece Agent Skills ou um servidor MCP para que o agente possa listar, preencher e testar conteúdo? E o carregamento de conteúdo é otimizado por padrão, ou alguém precisa revisar namespaces e lazy imports a cada trimestre?
Type safety pronto para uso.
Não "pode ser tipado com configuração extra", mas "uma chave errada falha no tsc em uma instalação nova". Verifique o que acontece com uma chave inexistente e com um locale que está com uma tradução faltando.
Detecção de conteúdo não utilizado.
Os catálogos só aumentam. O build do Intlayer purga campos não utilizados e registra logs (build.purge). O Paraglide atinge isso por arquitetura, já que uma função de mensagem não chamada sofre tree-shaking. Todas as outras deixam essa limpeza para você.
Experiência do desenvolvedor (DX).
Tempo de configuração até a primeira string traduzida, um LSP ou extensão para VS Code que mostra a tradução ao passar o cursor e navega até a declaração, uma CLI para preencher, testar e sincronizar (push), e uma forma para não-desenvolvedores editarem conteúdo (editor visual ou CMS) sem a necessidade de um pull request.
Perguntas Frequentes
Sim para a maioria das equipes. Ele possui o maior ecossistema e o maior número de respostas na internet. Seus custos são reais, mas previsíveis: o runtime mais pesado, formato próprio de plural, além de type safety e escopo que você mesmo precisa configurar e manter.
Apenas se tamanho de bundle, tipos gerados ou verificações de chaves ausentes em tempo de build estiverem entre seus requisitos. Para uma aplicação pequena com dois locales, uma biblioteca de runtime é mais simples. O artigo sobre compilador vs. i18n declarativo explica o que os compiladores oferecem e onde podem falhar.
Parcialmente. Bibliotecas baseadas em chaves compartilham formato suficiente para que um adaptador de compatibilidade possa mapear uma API para outra, que é como os adaptadores do Intlayer funcionam. Formatos de mensagem (ICU vs. i18next vs. helpers) não são convertidos automaticamente, então plurais e interpolações são a parte que você precisará ajustar.
Indiretamente. O que os crawlers veem é decidido pelo roteamento, hreflang, <html lang> e se o texto está no HTML renderizado pelo servidor. Algumas bibliotecas incluem utilitários para isso, a maioria deixa por sua conta. Veja o guia de hreflang.
Indo além
- Benchmark de bibliotecas de i18n: tamanho de bundle, vazamento e tempo de troca de locale e o relatório para TanStack Start
- React i18n: como funciona o modelo de provider e quanto ele custa
- react-i18next vs react-intl vs Intlayer, recurso por recurso
- next-i18next vs next-intl vs Intlayer
- A história do JavaScript i18n
- Compilador vs. i18n declarativo
- i18n por componente vs. centralizado
- Como funciona a otimização de bundle em tempo de build
- Configure i18n em uma aplicação Vite + React
- O mesmo guia para Vue, Svelte e Solid
Comentários
Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.
