The Double-Edged Nature of Next.js: Innovation vs. Control

by Dennis — 5 minutes

Next.js is one of the most popular frameworks in the React community. It is fast, packed with features, and backed by Vercel, a company that moves quickly and ships new ideas all the time. Think App Router, Server Components, and now metadata streaming in version 15.1. That speed is exciting. But it also comes with downsides. The idea of this article started after a chat at Divotion, when we read this post by Omar Abid titled "Next.js 15.1+ is unusable outside of Vercel". It led to a bigger question: is Next.js still a good choice if you are not running everything on Vercel? In this article, I want to share my view. Next.js is powerful and modern, but it can be hard to use if you want more control or need to work with a custom setup. It gives you a lot, but you also lose some flexibility. Let’s take a closer look.

Vercel Comes First

Next.js works best when you run it on Vercel. Many features are built with Vercel in mind, and some of them only work there. If you try to run your app somewhere else, things get harder very quickly. Most frameworks today use something called "adapters" to support different hosting providers. Think of it like a plug that fits into different sockets. SvelteKit, Astro, and Remix all have this idea. Next.js does not. Its build output is custom, and Vercel is the only company that understands it.

There was once a way to run Next.js as a serverless app on other platforms, but that was removed in 2022. Since then, there is no official way to deploy to a serverless provider like AWS Lambda or Cloudflare Workers. Some tools like OpenNext try to fix this. They recreate the build output so you can host your app elsewhere. Also, Kent C. Dodds mentioned in this article that OpenNext only exists because Next.js is hard to run outside of Vercel. In his words: "The line between Next.js and Vercel is paper thin, and that is a problem if you ever want to leave."

Learning Next Instead of React

Next.js moves fast. Sometimes a little too fast. With every new release, features are added or changed in ways that feel more like experiments than stable updates. Features like the App Router, Server Components, and now metadata streaming have all landed quickly. And often, they are marked as the new default before the community has fully wrapped its head around them.

This puts pressure on developers to keep up. You are not just learning React anymore; you are learning Next’s version of React. You need to understand how fetch behaves in a Server Component, what triggers a React Server Component request, or why some headers can only be set in middleware. These are not React problems. They are Next.js problems.

Mayank, in his article “The Good, the Bad, and the Ugly of React Server Components”, breaks this down well. He explains how Next.js wraps and changes parts of React in ways that make things more confusing. For example, you do not have full access to the request object. You cannot set headers from inside a route handler. You are expected to use fetch, but it is cached by default in a way that can lead to unexpected bugs.

All of this makes it harder to build reliable, predictable apps. Especially in larger teams where consistency and debugging matter a lot. Next.js is trying to solve real problems. But shipping these big changes so quickly and making them the default creates a lot of noise and confusion. You spend more time learning how Next.js wants you to build things than thinking about what your app needs.

Where Next.js Shines

Despite all the friction mentioned earlier, there is a reason why so many developers enjoy working with Next.js. When you stay within the intended path, especially when deploying to Vercel, it can be a great experience. You get a fast development setup, file-based routing, built-in data fetching, strong documentation, and a growing ecosystem. Static generation, server rendering, and automatic page updates are all handled for you. If you want to build something quickly and deploy it without thinking much about infrastructure, Next.js is one of the best tools out there.

The App Router, while more complex than the older Pages Router, does bring structure. It gives you clear patterns for layouts, loading states, and error handling. Server Components can also reduce the amount of JavaScript sent to the browser, and in simple setups, they can help you fetch and render data more cleanly. And Vercel takes this even further. If you follow the setup they offer, you get automatic deployments, preview environments, image optimization, and built-in analytics. All of this works with very little configuration.

Final Thoughts

Next.js is an impressive framework. It brings a lot to the table: routing, data fetching, rendering options, and a smooth developer experience when used together with Vercel. For small teams or personal projects, it can help you move quickly and build something solid without setting up much yourself.

But that power comes with tradeoffs. It moves fast, often introduces experimental features as defaults, and is deeply connected to one specific platform. That is not a bad thing by itself. But it does mean you give up some control, and need to follow the way Next.js wants you to build and deploy.

For me, that is where the balance shifts. In an enterprise environment, you often need predictable updates, more control over infrastructure, and room to make your own choices. In those cases, I would not pick Next.js very quickly.

It is a solid tool, just not always the right one for every job.

meerdivotion

Cases

Blogs

Event