- O middleware do Next.js tem configuração de logging limitada, e o logging padrão só é ativado no ambiente de desenvolvimento, o que dificulta rastrear problemas em produção
- No middleware, só é possível repassar headers, e não há suporte a encadeamento de múltiplos middlewares, o que limita implementações de logging mais complexas
- O logging com AsyncLocalStorage apresenta comportamento inesperado no runtime Edge, e o compartilhamento de contexto entre páginas e middleware não funciona corretamente
- Mesmo usando um servidor customizado, é difícil resolver os problemas de logging, e as restrições de design do Next.js acabam forçando os desenvolvedores a seguir um modo específico de trabalho
- O SvelteKit da Vercel oferece middleware flexível e mecanismos de passagem de dados, mostrando um design mais amigável para desenvolvedores do que o Next.js
Contexto dos problemas de logging no Next.js
- Ao operar um serviço em Next.js e tentar implementar registro de logs em produção, descobre-se que o recurso de logging nativo só é ativado no ambiente de desenvolvimento
- Ao precisar implementar um sistema de logging adequado para produção, o desenvolvedor esbarra nas limitações do Next.js
Limitações do middleware
- Segundo a documentação oficial, o middleware é executado antes do roteamento e é adequado para implementar autenticação, logging e redirecionamento
- Na prática, os parâmetros que podem ser passados ao middleware são limitados a quatro, e, de fato, só os headers podem ser transmitidos de forma útil
- Não há suporte a uma estrutura de encadear ou compor vários middlewares
- No Node.js, já existem práticas consolidadas de middleware em frameworks como Express, mas no Next.js isso não pode ser aplicado de forma adequada
Tentativa de contornar com AsyncLocalStorage
- Houve uma tentativa de gerenciar instâncias de logging no nível do middleware usando pino e AsyncLocalStorage
- No middleware, é possível armazenar logs com um contexto exclusivo por requisição, mas verificou-se que isso só funciona normalmente no ambiente do navegador
- Isso acontece porque o middleware do Next.js usa por padrão o runtime Edge, e, mesmo ao configurar o runtime nodejs, o comportamento pode continuar instável dependendo do projeto
Problemas nos componentes de página
- Ao chamar a função de logging em páginas ou componentes de layout reais, logger() retorna null
- Existe um problema estrutural em que o contexto do logger criado no middleware não é repassado para o contexto de renderização assíncrona
- A única solução é transportar informações de logging, como requestId, em headers, o que torna o código mais complexo e também confunde a estrutura de imports
- Em componentes de cliente, uma separação estrutural semelhante também passa a ser necessária
Tentativa de adoção de servidor customizado
- Seguindo o exemplo de servidor customizado da documentação oficial, foi feito um experimento usando http.createServer e app.getRequestHandler do Next.js
- Nesse ambiente, tentou-se usar novamente o AsyncLocalStorage, mas o problema de não conseguir conectar o contexto entre middleware, página e servidor customizado voltou a ocorrer
- No fundo, o Next.js só usa o AsyncLocalStorage corretamente dentro de sua própria implementação interna, sem dar aos desenvolvedores o mesmo nível de controle
- Na prática, as únicas formas de passagem do middleware para a página são alterações em headers de resposta e movimentação de rota por redirect/rewrite
- Do ponto de vista do usuário, é muito difícil fazer extensões flexíveis ou passar contexto customizado
Comparação com o SvelteKit
- O SvelteKit da Vercel oferece um sistema de middleware mais flexível que o Next.js
- Por meio do objeto event.locals, é possível repassar dados da requisição livremente
- É possível definir várias funções handle e encadeá-las, facilitando a implementação de lógica complexa
- O SvelteKit mostra um design mais amigável para desenvolvedores, em contraste com as limitações do Next.js
- Embora o SvelteKit também seja um produto da Vercel e seja visto como um projeto secundário em relação ao Next.js, ele ainda oferece uma experiência melhor
Críticas ao issue tracker e à cultura do ecossistema
- O issue tracker oficial no GitHub do Next.js praticamente não responde ao feedback dos usuários
- Mesmo issues populares ou bugs conhecidos frequentemente ficam abandonados por muito tempo, sem resposta ou correção
- Mesmo preparando um código mínimo de reprodução e abrindo uma issue, não há resposta concreta nem acompanhamento
Conclusão e reflexão
- Os bugs e limites estruturais encontrados no Next.js prejudicam repetidamente a produtividade dos desenvolvedores e indicam a necessidade de melhorias fundamentais
- Em comparação com outros frameworks, como o SvelteKit, o Next.js fica atrás em usabilidade apesar de ser o produto principal
- Não é fácil substituir o Next.js imediatamente, mas cresce a vontade de considerar outras opções em projetos futuros
7 comentários
Parece que ainda não perceberam que o React prejudica a produtividade.
Desta vez, por interesse pessoal, experimentei fazer desenvolvimento web, uma área totalmente sem relação com a área em que eu originalmente desenvolvia. Fiz um fórum com
next.js v15 app router... mas sempre que vejo textos assim, parece que perco a vontade de tentar algo novo no lado web. Por que o ecossistema é tão instável assim? Aí, quando surgir outra novidade, vai todo mundo correr em massa para ela, usar um pouco, depois reclamar de novo e procurar outra coisa? Desenvolvimento web realmente deve ser bem difícil.A velocidade das mudanças no setor pode ser tanto uma vantagem quanto uma desvantagem, né haha. Mas o problema do texto, no fundo, é causado pela bagunça que a Vercel vem fazendo. Se você vai trabalhar com front-end, vale a pena ficar bem de olho na Vercel T_T
Talvez porque eu tenha começado minha carreira na web, mas a web (especialmente o front-end) sempre foi desenvolvida com esse jeitão(?) mesmo haha
Com aquele gostinho de mudar o tempo todo...
O pessoal do lado de JS é meio assim mesmo. Tem um monte de coisas que dizem ser boas, mas todas têm algum probleminha, e as tendências mudam rapidinho conforme a moda...
Pode ser que eu sinta isso por ter trabalhado principalmente com Java, EJB e Struts.
Comentários do Hacker News
Concordo 100%, passei exatamente pelos mesmos problemas e nunca mais vou usar Next.js; também pretendo recomendar a todos os times da empresa que usem alternativas
O Next.js tem uma camada absurda de abstração que não é necessária em 99,9999% dos projetos, e acho que, nos poucos casos em que isso realmente seria necessário, seria melhor montar uma solução sob medida com componentes de nível mais baixo
De todas as tecnologias que já usei, Next.js foi de longe a pior
Ainda bem que não sou o único que pensa assim
Construí um app de produção com monetização e complexidade média usando Next.js; no começo usei Vercel e Google Firebase, depois migrei para hospedagem própria e troquei por Pocketbase
Pocketbase foi a única parte da experiência que prestou; todo o resto foi realmente terrível
Complexidade infinita, breaking changes o tempo todo, documentação difícil de acessar — nada era simples
Tenho certeza de que estaríamos em situação melhor hoje se tivéssemos rebobinado as tendências de frontend dos últimos 5 anos e focado em ensinar direito as tecnologias que já existiam na época
Também fiz alguns frontends complexos com React; não gosto muito de React, mas Next.js foi ainda pior
Também fiz um CMS com Go e JS puro; talvez o DX fosse um pouco pior, mas pelo menos eu tinha a sensação de realmente saber o que ia acontecer
Não entendo por que, com React e Next.js, mesmo depois de 6 anos, eu ainda tenho que ficar adivinhando o que vai acontecer
Ganhei experiência em contornar as bizarrices do framework, mas, no geral, tudo parece bagunçado demais e mal projetado
Em Go, tirando os primeiros 6 meses, quase nada me surpreendeu, e até codebases antigas continuam sólidas
É uma pena não conseguirmos ter esse tipo de experiência também no frontend
Pela minha experiência, as partes mais ásperas do Next.js não são bugs, são features
Tudo parece pensado para fazer o usuário desistir e ficar preso à hospedagem da Vercel
Acho que a situação só vai piorar daqui para frente
Até cursos online como os da PluralSight estão empurrando só Next.js nas aulas relacionadas a React
Não sei como essa situação se formou, mas chegamos aqui
No meu caso, Sharepoint me deixou lembranças mais traumáticas, então Next.js fica em segundo lugar entre os piores
O mais frustrante no Next.js é que ele finge oferecer tudo como frameworks full stack tipo Rails, Wordpress e Meteor, mas, na prática, só tem opinião sobre as partes menos interessantes e mais limitadas, como middleware, redimensionamento de imagem, SSR etc., enquanto empurra para o usuário as decisões que realmente têm valor, como banco de dados, ORM, protocolo de comunicação e por aí vai
Na prática, ele é bem diferente de Rails/Wordpress/Meteor; um framework deveria definir a infraestrutura, mas aqui a infraestrutura acaba mandando no framework
No meu dashboard, "Fluid Active CPU" e "ISR Writes" são os principais itens de consumo, e eu só pago $20 torcendo para não passar de 100%
Os nomes dos itens parecem jargão técnico saído de Star Trek, e como provavelmente tudo vai mudar de novo na próxima major, nem dá vontade de estudar
Muita gente que eu conhecia e que era fanática pela Zeit no passado acabou migrando projetos e clientes para outro lugar
Se a Vercel me perguntasse o que deveria mudar no próximo grande release, eu só conseguiria dizer: "Tudo o que veio a partir do App Router, incluindo o App Router, foi uma decisão errada"
Não sei como isso pode ser recuperado
Acho que muitos dos problemas do Next.js vêm do fato de você não saber direito onde o código está sendo executado
Browser, middleware, edge e node, SSR — tudo se mistura e gera uma complexidade enorme
Esse tipo de caso complicado faz sentido quando:
você opera um serviço B2C global e quer reduzir latência com semântica de edge
você está disposto a pagar pela hospedagem cara da Vercel
sua arquitetura não é complexa e não precisa de jobs em background
Fora disso, um SPA com react-vite ou SSR tradicional com Rails costuma ser muito mais tranquilo
Eu discordo até dessas condições
Mesmo que o seu caso combine com Next.js, a perda de produtividade e de manutenibilidade não parece valer a pena de jeito nenhum
Eu uso Lustre, da linguagem Gleam, e não pretendo voltar atrás
Também acho que a keynote do criador de Elm é um exemplo que vai na direção oposta à do Next.js
https://www.youtube.com/watch?v=sl1UQXgtepE
Eu diria que a Vercel é um câncer da web moderna
Ela se infiltra em todos os ecossistemas de framework e os explora para vender planos pagos, fingindo se importar com open source, concorrência e evolução da web
Mesmo no primeiro caso, é difícil acreditar que usar Vercel e SSR vá realmente resolver gargalos de performance
A maior parte dos problemas de desempenho vem de coisas básicas, como bundles grandes demais e um monte de chamadas lentas de API
Fazer o básico — profiling, otimização, simplificação — costuma ter muito mais efeito do que complicar a arquitetura
Concordo com a parte sobre "não saber onde o código é executado"
Antes eu achava que a ideia de JavaScript para tudo era uma vantagem, mas hoje sinto que isso virou um problema
Na nossa empresa usamos Inertia.js + Vue; no geral a estrutura é simples, mantém o poder do rendering no frontend, mas o roteamento é 100% do lado do servidor, e nem precisa de API separada
Dá para usar Inertia também com React e Svelte
No começo usávamos Nuxt, mas era complexo a ponto de termos que operar ao mesmo tempo um servidor backend e um servidor frontend, e era difícil saber onde o código rodava
Agora, com PHP no servidor e JS no browser, não preciso mais pensar nisso
Isso é uma vantagem enorme para nós
Acho que esse comentário resumiu bem o ponto
A Vercel está buscando otimização de performance com React Server Components, Partial Pre-rendering, servidores edge, streaming e afins
Todas essas decisões estranhas de design e API vêm daí
Em alguns casos isso até pode ajudar, mas muitas vezes já melhora bastante só usando SSR de forma adequada em algumas edge functions
Obrigado pelo feedback
Sabemos dos problemas de DX no Middleware, e na versão 15.5 demos um grande passo ao oferecer suporte ao runtime Node[1]
Se pudéssemos voltar atrás, talvez tivéssemos renomeado isso para algo como Routing Middleware ou Routing Handler, deixando mais claro que se trata de um escape hatch avançado na etapa de roteamento que pode ser enviado para o CDN edge
Se você precisa de logs, isso pode ser tratado com OpenTelemetry seguindo a convenção de
instrumentation.ts[2][1] https://nextjs.org/blog/next-15-5#nodejs-middleware-stable
[2] https://nextjs.org/docs/app/api-reference/file-conventions/instrumentation
Obrigado pela resposta
Mas, quando você traz instrumentation e observability para a conversa, soa como se um problema simples de logs estivesse sendo resolvido com mais uma camada complexa
Nem todo app precisa de OpenTelemetry
Não entendo por que algo comum como
logger().info()não pode simplesmente funcionarTodas as outras linguagens e frameworks têm isso; não consigo entender por que aqui é tão difícil
Como o clima aqui está negativo, quero deixar claro antes de tudo: Next.js é um ótimo software para o propósito real a que se propõe
Acho que fizeram um bom software para sustentar milhões de sites
O problema vem da falta de referências detalhadas e documentação; a documentação até mostra o que existe, mas não explica bem como usar de verdade, em que momento aquilo executa, quais são os erros comuns e assim por diante
Ela é amigável para iniciantes, mas faltam orientações sobre contextos complexos de runtime e a complexidade derivada disso
Essa parece ser uma tendência em muitos projetos hoje
É muito difícil equilibrar algo user friendly com explicações detalhadas
Espero que continue evoluindo
Só reforçando em uma frase
O autor deste post tentou chamar funções do mesmo jeito em todos os lugares, sem entender as diferenças entre os domínios
Os erros do Next.js vêm da tentativa de juntar à força domínios que originalmente têm naturezas diferentes
Quando você mistura edge, SSR, Node e client desse jeito, a complexidade só aumenta
Nem documentação resolve isso; só aumenta a confusão
Já recebi em comentário no Reddit a recomendação de usar instrumentation
Se eu tivesse tentado configurar opentelemetry no Next nessa mesma época, mesmo que a documentação fosse diferente, eu provavelmente teria escrito um post depois dessa experiência
A culpa não é de vocês, mas quase todos os pacotes de opentelemetry vêm marcados como experimentais, então isso não transmite confiança para uso em produção
Configurar instrumentation com pino também foi bem difícil
Foi preciso adicionar
pinoemserverExternalPackagespara funcionar direitoA auto-instrumentação também era extremamente sensível à ordem dos imports, e só instrumentava o default export do pino
Variáveis locais de módulo também não funcionaram como eu esperava, então tive que usar
globalThisE, mesmo assim, ainda bati neste problema: https://github.com/vercel/next.js/issues/80445
No fim, funcionou bem, mas configurar foi realmente desconfortável
Essa experiência foi com router manual (= sem usar
vercel/otel)Se a decisão foi dar suporte a middleware do lado do servidor, não entendo por que ainda não existe encadeamento de middleware, ou seja, conectar várias funções, e só é suportado um único middleware
É algo que praticamente todo framework de servidor oferece
Tenho dificuldade em acreditar que seja verdade que "não dá para encadear vários middlewares"
https://nextjs.org/docs/messages/nested-middleware
Dizer que, se houver vários, eles precisam ser combinados em um único arquivo para executar é realmente difícil de acreditar
Se entendi direito, o Next.js está basicamente dizendo para não estruturar isso em vários arquivos e juntar tudo em um só?
É por causa de problema de escopo que fica difícil usar vários arquivos? Para um framework, isso é uma exigência absurda
Não consigo deixar de suspeitar que a maioria dessas decisões absurdas não foi tomada para beneficiar o framework em si, mas porque favorece mais a Vercel
Quando vi Next.js pela primeira vez, pensei imediatamente em Meteor.js
Até investi um bom tempo aprendendo para um projeto pessoal, mas era difícil sair do estágio de protótipo por causa do excesso de abstração e da rigidez
Essas soluções “batteries included” continuam aparecendo porque a configuração é conveniente
Recentemente, no Hacker News, também houve comparações entre Laravel e Symphony falando que esse tipo de abordagem quebra quando a complexidade aumenta
Se você compara isso com montar sua própria composição, como no antigo NodeJS/React SPA, cada peça fica mais independente em abstrações de baixo nível, o que dá mais flexibilidade e facilita substituir partes específicas
Tem suas desvantagens, mas ainda assim costuma ser mais fluido do que overengineering, isto é, complexidade empilhada
Entendo perfeitamente por que soluções batteries included fazem sucesso
Juntar várias ferramentas e bibliotecas e fazer tudo conversar é realmente muito trabalhoso
Esse tipo de abordagem composável costuma funcionar bem quando alguém mais experiente faz a configuração
Sou acostumado com asp.net, e embora exista muito preconceito contra ele na comunidade de desenvolvimento de startups, na prática é um framework extremamente bem projetado
Ele é batteries included, mas eu sempre podia sair do caminho do framework e sobrescrever o que fosse necessário, e nunca tive a sensação de estar brigando com ele
Blazor Server e Blazor Webasm permitem usar C# no frontend, e ambos funcionam bem para painéis internos ou apps SaaS
E, acima de tudo, também dá para resolver tudo com renderização tradicional do lado do servidor
Se alguém está frustrado com frameworks web, eu realmente recomendaria experimentar
Hoje ele tem ótimo suporte cross-platform, é rápido e fácil de aprender
Existe uma curva de aprendizado, mas, entendendo a estrutura de módulos, eu conseguia sobrescrever o que quisesse com facilidade
Comparado com outros frameworks, era muito raro eu bater em limitações
Essa ideia de peças composáveis como no NodeJS/React SPA é meio estranha em Angular
Angular não é uma biblioteca, é um framework, então a maior parte do que você precisa já vem incluída
(O RxJS tem uma curva de aprendizado, mas, dominando o básico, já fica bem poderoso)
Em geral, eu quase nunca tive a sensação de estar brigando com o framework em SPA
A documentação e os tutoriais, incluindo o Tour of Heroes, são excelentes
https://v17.angular.io/tutorial/tour-of-heroes
A documentação mais nova está em https://angular.dev/
Laravel é um caso de sucesso de abstração com overengineering
Nunca me arrependi de usar Laravel em produção
Mudando um pouco de assunto, meu trabalho inteiro é basicamente conectar ferramentas e bibliotecas pequenas que vivem sendo ligeiramente incompatíveis entre si
Nosso time é pequeno, então gastamos um tempo enorme só atualizando e fazendo manutenção, e problemas com pacotes abandonados há muito tempo acontecem com frequência
Não é só a experiência; o tempo inicial para montar o sistema e o custo de manutenção são muito maiores do que parecem
Quando fiz isso na prática, Rails me pareceu 10 vezes mais produtivo do que ficar colando bibliotecas em Node
Só vira problema se você não gostar dos fundamentos e da filosofia do framework, por exemplo, se odeia ActiveRecord
Dizer que "quebra quando a complexidade sobe" é falta de competência técnica
Eu sou bem defensor de React e gostei da transição de class components para hooks
Mas toda vez que uso Next.js fico sem a menor ideia de onde as coisas começaram a dar errado
Eu gosto de muitos frameworks e até de linguagens exóticas, mas Next.js é o único caso em que eu não entendo nem metade das mensagens de erro
Especialmente o tempo absurdo que perdi com problemas estranhos de hydration
Eu não costumo usar React nem Next.js
Pessoalmente prefiro HTML+CSS com um pouco de JS puro
Já vi até uma landing page simples em Next.js quebrar no Firefox
O pior é que a falha aparecia como uma tela preta com letras brancas por cima de todo o conteúdo dizendo apenas "An application client side error has occurred"
Fiquei surpreso por uma landing page simples nem conseguir renderizar, e depois que descobri que era por causa de um framework frontend em JS, minha reação foi só “é, faz sentido”
Para quem tenta convencer usuários, isso talvez seja aceitável, mas para quem está fora da bolha da indústria pode ser desconcertante
Acho que o Next já é um caso de algo que se estragou sozinho
Lugares que passam pelo ciclo de VC acabam assim mesmo
Agora não consigo mais usar, e Vite virou a opção padrão
Sempre prefiro soluções leves
O termo “middleware” no Next.js induz facilmente ao erro
Na prática, é uma edge function leve executada antes de a requisição chegar ao app, para coisas como checar headers, fazer roteamento e guards simples
Ela roda no runtime edge, que é um ambiente separado do servidor da aplicação
O autor também parece estar confundindo runtime edge com runtime de servidor
Eu também me confundia no começo, e por tudo ser centrado em JavaScript a separação fica nebulosa
Acho que é preciso ter um modelo mental claro
Culpar a complexidade do Next.js me soa um pouco como reclamar que uma caixa de ferramentas tem mais coisas além de um martelo
O problema é que a complexidade do Next.js é autoinfligida
O termo middleware já tem um significado bem estabelecido em praticamente todos os frameworks
Normalmente middleware é uma cadeia de funções chamada antes da requisição no runtime, com a suposição de execução no mesmo processo
No Next.js, isso foi jogado para o edge e limitado a uma única unidade
Na maioria dos apps, nem há necessidade de usar recursos de edge, então isso deveria ser opt-in apenas quando necessário
Na analogia da caixa de ferramentas, o certo seria adicionar só as ferramentas de que você realmente precisa
O termo “middleware” não deveria ser usado nesse contexto no Next.js
Isso não é só uso indevido, é abuso do termo
Middleware tem uma definição antiga e consolidada na indústria de aplicações web; se vai significar algo completamente diferente, não deveria ter esse nome
Eu uso o app router do Next.js e estou satisfeito
Com Next.js é muito fácil ir e voltar entre frontend e backend, e acho que isso faz as pessoas pensarem que essa parte também foi abstraída
Na realidade, é um sistema muito complexo, e você mesmo precisa arcar com essa complexidade
Mais complexidade nem sempre significa lentidão ou improdutividade
Um sistema com frontend e backend separados costuma ser bem mais fácil de lidar, mas também é mais trabalhoso
Mesmo sabendo React, Next.js parece algo totalmente novo, e há muita coisa que você só entende vivendo a experiência
Ainda assim, depois que você pega certa familiaridade, ele vira um sistema muito conveniente para transitar entre frontend e backend com facilidade
Muita gente deu downvote no meu comentário, mas eu gostaria que explicassem por quê
Estou sempre disposto a aprender
Em discussões assim, seria melhor debater de verdade em vez de só reagir negativamente por reflexo
Finalmente vi uma opinião sensata
Por exemplo, seria como confundir sem pensar o conceito de pacote/módulo em Python com o conceito de módulo em Go e depois reclamar que Go é ruim
É preciso pelo menos uma compreensão básica da tecnologia que se está usando
Depois que o Next.js mudou para o app router, fiquei com a sensação de que pegaram a tarefa de melhorar a API do express e entregaram para recém-formados de bootcamp
A API do express, apesar de suas limitações, ainda é uma abordagem madura, especialmente porque todas as interfaces de servidor — servlets, rack, plug etc. — convergiram ao longo dos anos para um design tipo boneca russa
Além da API péssima de middleware, também foi uma decisão estranha eliminar parâmetros de requisição e substituí-los por funções globais como
cookies()eheaders()Parece haver alguma restrição arquitetural básica escondida aí, mas, de fora, dá a impressão de que jogaram fora todas as lições aprendidas e decidiram repetir os mesmos erros
E isso ainda foi agravado pela tentativa de suportar um runtime edge lowest common denominator
Eu sempre tento usar stacks diferentes em projetos novos
Já usei frontend e backend com express+react, angular, vue, next, nuxt, go, .net, node, php e por aí vai
Na maioria dos frameworks eu encontro pontos fortes e fracos, e ainda me divirto aprendendo algo novo
Next.js é a única exceção: construindo um app relativamente grande, do início ao fim tudo pareceu estranho, lento, inconveniente ou absurdamente mal projetado
Até hoje ainda faço manutenção nele, e é a única “coisa” que eu realmente odeio
Dizem que o ecossistema é bom e popular, mas, pela minha experiência real, foi algo irreversivelmente negativo
É estranho, mas é a realidade
Alguém por acaso sabe o endereço postal da Vercel?
No ano que vem esse issue já vai ter idade para entrar na escola primária, então queria mandar para a empresa um cartão de “bom começo de vida escolar!”
https://github.com/vercel/next.js/issues/10084
O comentário do Hacker News logo abaixo está certíssimo.
"O Next.js tem uma camada de abstração enorme e desnecessária para 99,9999% dos projetos; e, nos poucos casos em que isso realmente seria necessário, acho muito melhor criar uma solução sob medida com componentes de nível mais baixo"
APIs excessivamente complexas sem necessidade, a postura de promover algo instável e incompleto como se fosse
production ready, e uma dependência absurda da Vercel que torna difícil até operar de verdade sem usar a Vercel.