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
i18next VS Intlayer | Benchmark de internacionalização (i18n) para React e Next.js
O i18next é o framework de i18n mais utilizado no ecossistema JavaScript. Através do react-i18next e next-i18next, sustenta grande parte das aplicações React e Next.js. O Intlayer é uma alternativa baseada em compilador, com escopo por componente.
Este artigo compara ambas as soluções com base em medições reais e não em listas de recursos. Os números vêm do Benchmark Bloom, uma suíte de código aberto que constrói a mesma aplicação com cada biblioteca e registra o que o navegador realmente baixa.
tl;dr: Oi18nexté o runtime mais pesado do benchmark: +77 KB gzip por página no Next.js na configuração padrão (naive), +22 KB após otimização completa de namespaces + lazy loading. O Intlayer adiciona apenas +0.3 KB. Todas as configurações doi18next, exceto a totalmente isolada (scoped), enviam ~90% de strings de outras páginas; o Intlayer envia 0% por padrão. A troca de idioma com backend carregado sob demanda levou 123-185 ms com oreact-i18nextcontra 3-4 ms com o Intlayer. O adaptador@intlayer/next-i18nextmantém a API doi18nexte atingiu 150.7 KB por página contra 218.5 KB do original.
Em resumo
- i18next / react-i18next / next-i18next - Maduro, com ecossistema rico de plugins e agnóstico de framework. Namespaces, detectores de idioma, backends, ICU via plugin,
<Trans>para conteúdo rico. Conteúdo centralizado emlocales/{lng}/{ns}.json. Poderoso, mas cada otimização (divisão de namespaces, carregamento por página, segurança de tipos) exige configurações manuais contínuas. - Intlayer - Modelo de conteúdo centrado em componentes. Dicionários
.content.tsficam ao lado do componente que atendem, um compilador em tempo de build aplica tree-shaking e lazy loading por componente e por idioma, tipos TypeScript estritos são gerados a partir do seu conteúdo e traduções ausentes quebram o build. Oferece middleware, utilitários de SEO, Editor Visual / CMS e tradução assistida por IA.
Abrir a tabela em um modal para ver todo o conteúdo claramente
Os badges são atualizados automaticamente. As capturas variam ao longo do tempo.
Comparativo direto de recursos
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Recurso | Intlayer (react-intlayer / next-intlayer) | i18next (react-i18next / next-i18next) |
|---|---|---|
| Traduções próximas aos componentes | ✅ Sim, .content.ts junto a cada componente | ❌ Não, pastas centralizadas locales/{lng}/{ns}.json |
| Integração com TypeScript | ✅ Tipos estritos gerados automaticamente do conteúdo | ⚠️ Básico; chaves estritas exigem ampliação de CustomTypeOptions e tipagem |
| Detecção de traduções ausentes | ✅ Erro TypeScript + erro/aviso no momento do build | ⚠️ Fallback em runtime (saveMissing, eco de chave) |
| Conteúdo rico (JSX / Markdown) | ✅ Suporte nativo | ⚠️ <Trans> com placeholders indexados |
| Suporte ICU | ⚠️ Em andamento | ⚠️ Via plugin (i18next-icu) |
| Pluralização | ✅ Padrões baseados em enumerações | ✅ Sufixos _one / _other (Intl.PluralRules) |
| Formatação (datas, números, moedas) | ✅ useNumber, useDate, ... (Intl nativo) | ⚠️ Formatadores de interpolação ou chamadas diretas a Intl.* |
| Roteamento localizado e middleware | ✅ Proxy/middleware integrado, getMultilingualUrls | ⚠️ Não é nativo; middleware manual ou de terceiros |
| Utilitários de SEO (hreflang, sitemap) | ✅ Utilitários integrados | ❌ Manual |
| Componentes de servidor síncronos | ✅ useIntlayer de next-intlayer/server utilizável em qualquer Server Component | ⚠️ getFixedT na página e passar t via props |
| Tree-shaking (apenas conteúdo utilizado) | ✅ Por componente, por idioma, automatizado pelo compilador | ⚠️ Manual: namespaces + lista ns por página + backend |
| Lazy loading | ✅ importMode: 'dynamic' (uma linha de configuração) | ✅ Via plugins backend (i18next-resources-to-backend, i18next-http-backend) |
| Limpeza de conteúdo não utilizado | ✅ Dicionários órfãos são descartados no build | ❌ Não integrado |
| Testar traduções ausentes (CLI / CI) | ✅ npx intlayer content test | ⚠️ i18next-parser / ferramentas de terceiros |
| Tradução assistida por IA | ✅ Integrada, utiliza suas próprias chaves de API | ❌ Não (Locize é um serviço pago à parte) |
| Editor Visual / CMS | ✅ Editor Visual gratuito + CMS opcional | ❌ Não (Locize / plataformas externas) |
| Servidor MCP e Agent Skills | ✅ Sim | ❌ Não |
| Ecossistema e comunidade | ⚠️ Mais recente, porém em rápido crescimento | ✅ Maior e mais maduro |
O benchmark
O que foi medido
A suíte Benchmark Bloom constrói a mesma aplicação com cada biblioteca: 10 páginas (home, about, blog, careers, contact, FAQ, pricing, products, settings, team), 10 idiomas (en, fr, es, de, it, pt, zh, ja, ko, ru), componentes e conteúdos idênticos. As páginas são medidas em en e fr. Cada biblioteca é testada em até quatro estratégias de carregamento:
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Estratégia | Descrição | Quem costuma usar |
|---|---|---|
| static | Todos os idiomas e páginas empacotados juntos (resources embutidos em init()) | Protótipos rápidos, código gerado por IA |
| dynamic | Apenas o idioma ativo é carregado via backend, mas todos os namespaces simultaneamente | A maioria dos projetos |
| scoped-static | Um namespace por rota, todos embutidos antecipadamente | Raro |
| scoped-dynamic | Um namespace por rota + lazy loading via backend. Apenas a página e idioma atuais | Aplicações com orçamento de performance rígido |
O Intlayer não possui variante "scoped": o compilador isola o conteúdo por componente automaticamente, logo suas linhas static e dynamic já são otimizadas.
Para cada build, a suíte registra:
- Lib size: tamanho gzip de um componente vazio que apenas importa a biblioteca i18n. O custo fixo do runtime.
- Page JS: JavaScript gzip baixado por página, com média calculada sobre todas as páginas e idiomas.
- Locale leak %: proporção de strings traduzidas no JS baixado que pertencem a um idioma que o usuário não está visualizando.
- Page leak %: proporção de strings traduzidas no JS baixado pertencentes a páginas nas quais o usuário não está.
- Component avg: tamanho médio gzip de cada componente compilado isoladamente.
- E2E reactivity: intervalo real entre a seleção de um novo idioma e a atualização de
html[lang]no DOM (Playwright, 5 iterações). - Hydration: duração da fase de hidratação do React.
Os dados abaixo provêm da execução de 2026-09-12 comnext-i18next16.3.0,react-i18next17.0.13 eintlayer9.5.1. A aplicação de teste é deliberadamente enxuta (poucas dezenas de strings por idioma), portanto as porcentagens de vazamento expressam um padrão: crescem com o volume do conteúdo enquanto o custo do runtime permanece constante.
Resultados no Next.js (next-i18next)
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Biblioteca | Estratégia | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | Reatividade E2E | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (sem i18n) | - | 0.0 KB | 141.0 KB | 0.0% | 0.0% | 0.9 KB | 13.4 ms | 11.8 ms |
next-i18next | static | 19.7 KB | 218.5 KB | 0.0% | 89.8% | 78.5 KB | 16.4 ms | 15.6 ms |
next-i18next | dynamic | 19.7 KB | 169.5 KB | 50.0% | 89.8% | 26.1 KB | 15.4 ms | 27.7 ms |
next-i18next | scoped-static | 19.7 KB | 220.1 KB | 0.0% | 89.8% | 78.9 KB | 16.4 ms | 14.7 ms |
next-i18next | scoped-dynamic | 19.7 KB | 163.4 KB | 0.0% | 0.0% | 27.1 KB | 15.9 ms | 15.1 ms |
next-intlayer | static | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 8.5 KB | 15.5 ms | 16.9 ms |
next-intlayer | dynamic | 5.5 KB | 141.3 KB | 0.0% | 0.0% | 6.9 KB | 15.3 ms | 15.9 ms |
@intlayer/next-i18next (compat) | static | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 10.7 ms | 11.3 ms |
@intlayer/next-i18next (compat) | dynamic | 9.4 KB | 150.7 KB | 0.0% | 0.0% | 9.7 KB | 11.9 ms | 10.6 ms |
Como interpretar os dados
- Custo do runtime. O core do
i18nextsomado aoreact-i18nextrepresenta o maior runtime medido: 19.7 KB gzip para um componente vazio, contra 5.5 KB donext-intlayer. - A configuração inicial é onerosa. Embutir
resourceseminit()gera 218.5 KB por página, +77.5 KB acima da aplicação base. Cada página carrega todos os namespaces. - Otimizar exige muito esforço. Adotar um backend (
dynamic) reduz 49 KB mas ainda vaza 90% de strings de outras páginas e, nesta configuração, metade das strings pertence ao idioma errado. Dividir em namespaces por rota (scoped-dynamic) atinge 0% de vazamento com 163.4 KB, permanecendo +22.4 KB por página acima do Intlayer (141.3 KB), que não exigiu configuração manual alguma. - Tamanho dos componentes. Um componente invocando
useTranslation()compila entre 26 e 79 KB; o mesmo componente comuseIntlayer()compila em 6.9 KB. - A hidratação sobe para 27.7 ms na configuração
dynamic: a instância do i18next inicializa e resolve o backend no cliente antes de o React conseguir hidratar a página.
Resultados no TanStack Start (react-i18next)
A mesma aplicação no TanStack Start com react-i18next puro, isolando os efeitos específicos do Next.js.
Abrir a tabela em um modal para ver todo o conteúdo claramente
| Biblioteca | Estratégia | Lib size (gz) | Page JS avg (gz) | Locale leak | Page leak | Component avg (gz) | Reatividade E2E | Hydration |
|---|---|---|---|---|---|---|---|---|
| base (sem i18n) | - | 0.0 KB | 111.0 KB | 0.0% | 0.0% | 0.7 KB | 8.1 ms | 21.6 ms |
react-i18next | static | 18.4 KB | 180.3 KB | 50.0% | 89.8% | 24.3 KB | 12.9 ms | 85.1 ms |
react-i18next | dynamic | 18.4 KB | 136.4 KB | 23.1% | 89.8% | 24.8 KB | 123.1 ms | 32.9 ms |
react-i18next | scoped-static | 18.4 KB | 184.2 KB | 50.7% | 89.8% | 25.3 KB | 185.1 ms | 25.2 ms |
react-i18next | scoped-dynamic | 18.4 KB | 127.2 KB | 0.0% | 0.0% | 26.7 KB | 17.6 ms | 11.3 ms |
intlayer | static | 5.0 KB | 125.8 KB | 50.0% | 0.0% | 8.1 KB | 3.2 ms | 11.5 ms |
intlayer | dynamic | 5.0 KB | 118.6 KB | 0.0% | 0.0% | 6.3 KB | 3.6 ms | 14.1 ms |
Como interpretar os dados
- A aplicação
react-i18nextbásica entrega +69 KB por página em relação à aplicação base, e a hidratação consome 85 ms (4 vezes a base) porque toda a árvore de recursos é processada e registrada no cliente antes do primeiro render. - A troca de idioma evidencia o atraso do lazy loading. Quando os recursos são carregados sob demanda, alternar de idioma exige uma viagem de rede antes da atualização do
html[lang]: 123 ms emdynamic, 185 ms emscoped-static. O Intlayer atualiza o DOM em 3-4 ms em ambos os modos: a troca é instantânea e não fica bloqueada em requisições de rede. - A configuração totalmente otimizada
scoped-dynamicatinge 0% de vazamento com 127.2 KB, ainda +8.6 KB acima da linhadynamicdo Intlayer, e demandou mapeamento de rotas para namespaces, backend de recursos e limites Suspense por rota. - A linha
staticdo Intlayer já apresenta 0% de vazamento de página porque somente os dicionários importados pelos componentes daquela página são empacotados. AtivarimportMode: 'dynamic'elimina também o vazamento de idioma. - Tamanho por componente: 24-27 KB com
react-i18nextcontra 6-8 KB com Intlayer. OuseTranslation()conecta cada componente à instância global do i18next.
De onde vem a diferença? Instância global vs. dicionários compilados
O i18next foi projetado em 2012 como um runtime: uma instância global mantém os recursos, plugins a expandem e t() busca chaves em tempo de renderização. Isso proporciona grande flexibilidade (qualquer framework, backend ou formato), mas impõe custo de peso:
Copiar o código para a área de transferência
A instância não tem como prever quais chaves um componente solicitará. Otimizar exige que você divida catálogos em namespaces, você liste os namespaces de cada página e você mantenha essa lista sincronizada ao mover componentes. Como destacam as notas do benchmark: "manter a segurança de tipos e saber com precisão qual namespace incluir em cada página é um pesadelo".
O Intlayer remove a instância global. O conteúdo é declarado ao lado do componente e o compilador resolve o grafo de dependências no momento do build:
Copiar o código para a área de transferência
O @intlayer/swc / @intlayer/babel identifica qual componente importa qual dicionário, inclui apenas esses, apenas para o idioma ativo, e descarta o que não for utilizado. O padrão "scoped-dynamic" passa a ser o resultado natural do build, e não uma disciplina manual mantida pela equipe.
Para reproduzir os números da linhadynamic, configuredictionary.importMode: 'dynamic'emintlayer.config.ts. Veja a documentação de otimização de bundle.
Experiência de desenvolvimento
Configuração
next-i18next (App Router)
Copiar o código para a área de transferência
Adiciona-se a isso um I18nProvider client-side que recria a instância com as mesmas configurações, generateStaticParams e uma lista de namespaces em cada página.
Intlayer
Copiar o código para a área de transferência
Copiar o código para a área de transferência
Componente de cliente
react-i18next
Copiar o código para a área de transferência
Copiar o código para a área de transferência
A página que renderiza este componente precisa carregar o namespaceabout, et("counter.label")é uma string simples a menos que você estendaCustomTypeOptions.
Intlayer
Copiar o código para a área de transferência
Copiar o código para a área de transferência
label e increment são estritamente tipados; erros de digitação tornam-se erros de TypeScript e uma tradução ausente causa erro na compilação.
Componente de servidor síncrono
next-i18next
Copiar o código para a área de transferência
A página invoca i18n.getFixedT(locale, "about") e propaga t e locale via props.
Intlayer
Copiar o código para a área de transferência
Mantenha a API do i18next, aproveite o desempenho do Intlayer
Você não precisa reescrever componentes para obter os números do benchmark. @intlayer/i18next, @intlayer/react-i18next e @intlayer/next-i18next são adaptadores compatíveis: useTranslation, t(), <Trans>, {{interpolation}}, plurais _one / _other, sufixos de contexto e returnObjects continuam operacionais, alimentados pelos dicionários compilados pelo Intlayer.
Copiar o código para a área de transferência
Copiar o código para a área de transferência
No benchmark, a versão adaptada da mesma aplicação Next.js caiu de 218.5 KB para 150.7 KB por página, de 78.5 KB para 9.7 KB por componente, de ~90% de vazamento para 0%, e a hidratação passou de 15.6 ms para 11.3 ms, mantendo o código da aplicação intacto. Seus arquivos locales/{lng}/{ns}.json existentes podem continuar sendo a fonte da verdade via plugin de sincronização JSON.
Consulte os guias de migração: i18next, react-i18next, next-i18next.
Quando escolher cada um?
- Escolha o i18next se você depende de seu ecossistema de plugins (detectores, backends, ICU, Locize), traduz também fora do React (serviços Node, vanilla JS, outros frameworks), seu time já possui domínio ou uma plataforma externa exige
locales/{lng}/{ns}.json. Reserve tempo para separar catálogos em namespaces, conectar um backend e manter o mapa de rotas se a performance for prioritária. - Escolha o Intlayer se busca conteúdo com escopo por componente, TypeScript estrito, detecção de chaves ausentes no build, tree-shaking e lazy loading automáticos, troca instantânea de idioma, componentes de servidor síncronos e ferramentas editoriais nativas (Editor Visual, CMS, tradução com IA, servidor MCP). Ideal para bases de código modulares e design systems.
- Escolha os adaptadores
@intlayer/*-i18nextse você já utiliza o i18next e quer os ganhos de bundle e reatividade sem precisar reescrever seus componentes.
Comparações relacionadas
- next-intl vs Intlayer (mesmo benchmark)
- Lingui vs Intlayer (mesmo benchmark)
- vue-i18n vs Intlayer benchmark (mesmo benchmark)
- next-i18next vs next-intl vs Intlayer
- react-i18next vs react-intl vs Intlayer
- O i18next está desatualizado?
Estrelas no GitHub
As estrelas no GitHub são um indicador sólido da popularidade, confiança da comunidade e relevância de longo prazo de um projeto. Embora não meçam diretamente a qualidade técnica, refletem o engajamento dos desenvolvedores e o potencial de adoção.
Conclusão
O i18next conquistou sua posição de destaque: roda em qualquer lugar, conta com plugins para tudo e possui mais de dez anos de manutenção contínua. O benchmark demonstra o custo de um design centrado no runtime. A configuração padrão da maioria dos times adiciona +70-77 KB gzip por página, vaza ~90% do conteúdo de outras páginas e leva mais de 100 ms para trocar de idioma com lazy loading. Chegar a 0% de vazamento é viável, mas requer backend, namespaces por rota e mapeamento manual, permanecendo ainda +9-22 KB acima do Intlayer.
O Intlayer transfere essa responsabilidade para o compilador. Dicionários por componente, lazy loading por idioma e eliminação de conteúdo inútil tornam-se saídas automáticas do build. Na mesma aplicação: +0.3 KB por página, 0% de vazamento, componentes 3 a 10 vezes menores e troca de idioma em 3-4 ms.
Todos os dados brutos, aplicações de teste e scripts estão disponíveis no repositório Benchmark Bloom. Execute e confira por conta própria.
Consulte a documentação 'Por que o Intlayer?' para obter mais detalhes.
Comentários
Ainda sem comentários. Seja o primeiro a compartilhar seus pensamentos.
