Nuxt 5: o que há de novo e como preparar sua aplicação cover image

Nuxt 5: o que há de novo e como preparar sua aplicação

Se você acompanhou o lançamento do Nuxt 4, já sabe que o time dividiu o roadmap em dois capítulos: o Nuxt 4 refinou a experiência de desenvolvimento, e o Nuxt 5 assume o trabalho pesado de infraestrutura por baixo dos panos. Isso significa menos novidades visuais e mais mudanças relevantes na forma como sua aplicação compila, empacota e responde requisições.

Em meados de 2026, o Nuxt 5 ainda está em desenvolvimento ativo, sem data final de lançamento. A boa notícia é que você não precisa esperar para começar a se preparar. A partir do Nuxt 4.2, é possível ativar a maior parte do comportamento da v5 com uma única flag de configuração e migrar de forma incremental. Este artigo percorre as principais novidades, as breaking changes que importam em produção e um caminho prático para o upgrade.

Teste o comportamento do Nuxt 5 antes do lançamento

O caminho oficial de upgrade começa com a atualização para a última versão do Nuxt 4 e, em seguida, a ativação da camada de compatibilidade:

export default defineNuxtConfig({
  future: {
    compatibilityVersion: 5,
  },
})

Definir compatibilityVersion: 5 altera vários padrões de uma vez. Você passa a ter a Vite Environment API, nomes de componentes de página normalizados, callHook não assíncrono, placeholders em comentários HTML para componentes client-only e clearNuxtState resetando para o valor inicial em vez de undefined.

Esse é o jeito certo de testar, mas trate como prévia. O guia de upgrade avisa explicitamente que o comportamento ainda pode mudar antes do lançamento final. Rode em uma branch, exercite seus fluxos críticos e acompanhe a documentação oficial em vez de assumir estabilidade no primeiro dia.

Nitro v3: a maior mudança

O centro do Nuxt 5 é o Nitro v3, uma reescrita importante do motor de servidor construída sobre srvx e h3 v2. Em vez de depender de objetos de requisição específicos do Node em todo lugar, o Nitro v3 adota as APIs Web Request e Response em toda a stack. O resultado é um modelo mental mais consistente, melhor desempenho e uma camada de servidor alinhada com a forma como runtimes modernos realmente funcionam.

Para a maioria dos desenvolvedores de aplicação, utilitários auto-importados como defineEventHandler, getQuery e readBody continuam funcionando. O atrito aparece em imports explícitos, tratamento de erros e código que acessa propriedades de baixo nível do evento.

Os principais pontos de migração incluem:

  • Renomeação de pacote: nitropack vira nitro. Atualize imports explícitos e augmentations de tipos em módulos.

  • Propriedades de erro: statusCode e statusMessage passam a ser status e statusText, seguindo os padrões Web.

  • API do evento: use event.url.pathname em vez de event.path, e event.req.headers em vez de event.node.req.headers.

  • Runtime config: useRuntimeConfig() não aceita mais o argumento event em rotas de servidor.

  • Route rules: regras de redirect usam status em vez de statusCode.

Se você mantém um módulo Nuxt ou compartilha utilitários de servidor entre projetos, reserve tempo real para essa migração. É a mudança de maior impacto de toda a release.

Vite 8 e Rolldown: builds mais rápidos, nova superfície de configuração

O Nuxt 5 faz upgrade do Vite 7 para o Vite 8, que substitui esbuild e Rollup pelo Rolldown como bundler subjacente. Na prática, isso significa builds de produção visivelmente mais rápidos — especialmente em codebases maiores — mas também um conjunto diferente de opções de configuração.

Diferente das mudanças ativadas pela flag de compatibilidade, não dá para pré-visualizar o Vite 8 apenas com compatibilityVersion: 5. Se quiser um sinal antecipado, adicione um override de resolução do Vite 8 no package.json e rode seu pipeline de build no CI.

Fique atento a estas depreciações:

  • vite.esbuild e vite.optimizeDeps.esbuildOptions migram para vite.oxc e vite.optimizeDeps.rolldownOptions

  • build.rollupOptions cede lugar a build.rolldownOptions

  • O comportamento de interoperabilidade com CommonJS mudou para algumas dependências legadas

A maioria dos projetos absorve isso de forma transparente, mas times com plugins Vite customizados ou árvores de dependência incomuns devem testar cedo.

Vite Environment API: uma config, plugins conscientes do ambiente

O Nuxt 5 adota por completo a Vite Environment API, que substitui o padrão antigo de manter configurações Vite separadas para client e server. Agora o Nuxt usa uma config Vite compartilhada, na qual os plugins declaram o ambiente alvo via applyToEnvironment() e configEnvironment().

Se você é autor de módulo ou customizou o build com extendViteConfig() e hooks vite:extendConfig, essa é uma migração de impacto médio. O caminho recomendado é mover a lógica para plugins Vite adequados:

addVitePlugin(() => ({
  name: 'my-plugin',
  configEnvironment(name, config) {
    if (name === 'client') {
      config.optimizeDeps ||= {}
      config.optimizeDeps.include ||= []
      config.optimizeDeps.include.push('my-package')
    }
  },
  applyToEnvironment(environment) {
    return environment.name === 'client'
  },
}))

A vantagem é mais consistência entre desenvolvimento e produção, além de uma arquitetura de plugins que escala além dos ambientes client e server.

Recursos voltados ao desenvolvedor que vale adotar agora

Embora o Nuxt 5 seja frequentemente descrito como uma release de infraestrutura, várias melhorias voltadas ao usuário chegaram na linha 4.x e seguem para a v5. Vale adotá-las independentemente de quando você mudar a major version.

  • Vue Router v5: o Nuxt faz upgrade para o vue-router v5, trazendo as APIs de navegação mais recentes e melhorias de tipagem para o framework.

  • unrouting: a geração de rotas baseada em arquivos agora usa a biblioteca unrouting, tornando a resolução de rotas mais previsível e sustentável ao longo do tempo.

  • createUseFetch / createUseAsyncData: funções factory permitem definir composables reutilizáveis de data fetching com defaults compartilhados — ideal para clientes de API, headers de autenticação e tratamento consistente de erros em monorepos.

  • useAnnouncer e NuxtRouteAnnouncer: primitivas de acessibilidade embutidas para anunciar mudanças de rota a leitores de tela, reduzindo boilerplate em SPAs acessíveis.

  • Melhorias em useState e clearNuxtState: o estado pode resetar para o valor padrão inicial em vez de undefined, o que torna fluxos de logout e reset de formulários mais previsíveis.

  • Opção refresh em useCookie: cookies agora podem reagir a mudanças externas por meio de um mecanismo de refresh, útil para tokens de autenticação atualizados por outra aba ou um iframe embutido.

  • Layout props em definePageMeta: passe props tipadas de layout diretamente nos metadados da página, sem precisar de middleware ou componentes wrapper.

  • Suporte a tipos de View Transitions: melhor cobertura TypeScript para a API View Transitions, que combina bem com o sistema de transição de página do Nuxt.

Nenhum desses pontos exige o Nitro v3, mas representam a direção do framework: tipos mais fortes, defaults melhores e menos cerimônia para padrões comuns.

Mudanças de runtime que você só percebe em produção

Algumas mudanças do Nuxt 5 são sutis, mas podem causar bugs difíceis de rastrear se você não estiver ciente delas.

callHook não assíncrono. Com o hookable v6, callHook pode retornar void em vez de sempre retornar uma Promise. Isso representa um ganho de performance de 20 a 40 vezes em apps com muitos hooks, mas quebra código que encadeia .then() ou .catch() em chamadas de hook. Troque para await.

Placeholders em comentário para client-only. Componentes com .client.vue ou createClientOnly() agora renderizam um comentário HTML no servidor em vez de um <div> vazio. Isso corrige um bug de hidratação em estilos scoped, mas se você dependia do div placeholder para layout (reservar espaço e evitar CLS), envolva o componente em <ClientOnly> com um slot #fallback explícito.

Nomes de componentes de página normalizados. Os nomes dos componentes de página agora correspondem aos nomes das rotas, o que torna <KeepAlive> e a inspeção no devtools mais consistentes. Revise qualquer código que referencia nomes de componentes por string — especialmente em testes ou hooks de transição.

Bundles de servidor menores. O Nuxt 5 remove experimental.externalVue e faz mock das dependências do compilador Vue no bundle de servidor por padrão, cortando cerca de 860KB da saída típica. Se você usa vue.runtimeCompiler: true, o comportamento permanece o mesmo.

Um checklist prático de migração

Esta é a ordem que recomendo para times que estão caminhando para o Nuxt 5:

  • Passo 1: atualize para a última versão do Nuxt 4.x e resolva warnings de depreciação existentes.

  • Passo 2: ative future.compatibilityVersion: 5 em uma branch de feature e rode sua suíte de testes.

  • Passo 3: audite rotas de servidor em busca de imports explícitos de h3, uso de event.path e createError com nomes de propriedades antigos.

  • Passo 4: revise plugins Vite customizados e chamadas a extendViteConfig com lógica específica por ambiente.

  • Passo 5: procure encadeamentos de callHook com .then() ou .catch() em módulos e plugins da aplicação.

  • Passo 6: rode um build de produção no CI com Vite 8 se você usa configuração customizada de bundler.

  • Passo 7: acompanhe o guia oficial de upgrade — ele é atualizado conforme a integração com o Nitro v3 estabiliza.

O que o Nuxt 5 não é

Vale alinhar expectativas. O Nuxt 5 não é um redesign completo de API como o salto do Nuxt 2 para o Nuxt 3. Se você já está no Nuxt 4 com a estrutura de diretório app/, contextos TypeScript separados e a camada moderna de data fetching, o modelo conceitual permanece familiar.

O que muda é a sala de máquinas: como o Vite configura ambientes, como o Rolldown empacota seu código e como o Nitro atende requisições usando APIs Web. Isso é menos empolgante em um screenshot de changelog, mas é exatamente o tipo de trabalho que torna aplicações Nuxt grandes mais rápidas, menores e mais fáceis de deployar em runtimes edge.

Comece testando com compatibilityVersion: 5, resolva primeiro as migrações de servidor e ferramentas de build, e adote os novos composables conforme eles resolverem problemas reais no seu código. Quando o Nuxt 5 sair estável, você já terá pago a maior parte do custo de migração — de forma incremental, no seu próprio ritmo.