A founder asked if we would rebuild their admin in “something faster than React.” The app was fine. The deploy model was not.
We still reach for Next.js most weeks. We leave it when three signals line up—not when a blog post says React is tired.
Signal one: the product is not a website
When the surface is a long-lived desktop tool, heavy client state, and websockets all day, a document-centric framework buys little. The team ships against a different mental model. We have moved those clients to Vite + a thin API layer, or a backend-for-frontend we control.
Signal two: edge and regional law fight the default hosting story
If every request must hit a specific jurisdiction, or you need predictable long-running workers on every request, the platform bill and architecture stop looking like a marketing site. We map data residency first. Then we pick the runtime.
Signal three: the team cannot operate the framework
Next.js is not “zero ops.” If there is no one who understands caching headers, ISR, and why a build failed, the org is paying for complexity without the skills to own it. Sometimes a boring server-rendered monolith and a single deploy target is the professional answer.
What we’d do differently next time
We have recommended Next when a simpler stack would have trained the client faster. Enthusiasm for file-based routing is not a strategy.
Our read
We leave Next.js when the job-to-be-done is not “ship pages with good defaults.” We stay when the product is the web, SEO matters, and the team wants one disciplined way to ship both UI and API routes. The stack is secondary to the operating model.