Next.js 16 landed late last year with a set of changes that looked, on paper, like mostly incremental improvements. Six months and five production client deployments later, we have a clearer picture of what actually shifted and where you still get tripped up. This is not a release notes recap — plenty of those exist. This is the honest production view from a small agency that has shipped it.
Turbopack as the Default: Real Impact, Real Edges
The loudest Next.js 16 change is Turbopack becoming the default bundler for both dev and build. The developer experience improvement is real — builds for our largest client project dropped from 2 minutes 40 seconds on webpack to 21 seconds on Turbopack. Dev startup is effectively instant.
The rough edges we hit in production:
- Static export (output: 'export') works on Turbopack now, but one of our CI deploys produced an out/ directory that was missing the sitemap.xml route — we had to switch to the webpack build for that one project as a workaround
- A couple of less-maintained plugins in our stack were not Turbopack-compatible and silently produced stale bundles. The error was not obvious — pages just did not reflect code changes until we figured out the culprit
- Build output differs slightly between webpack and Turbopack in ways that break some third-party bundle analyzers
Our rule of thumb: stick with Turbopack for new projects. If you are migrating an existing Next.js 13 or 14 app with a long plugin history, test the Turbopack build against every major route before trusting it in CI.
App Router is Now Genuinely the Default
It took three major versions but the App Router now feels like the right way to build. The mental model clicks once you accept that:
- Server components are the default and usually the right choice
- Client components are an escape hatch for interactivity, not a starting point
- Loading, error, and layout boundaries are first-class — not bolted on
- Parallel and intercepting routes solve real UI patterns that were genuinely hard before (modals as routes, dashboards with multiple concurrent loading states)
The App Router stopped feeling like a new way to build React apps and started feeling like React finally grew up.
The Caching Story Is Still The Trap
If there is one place where Next.js 16 has burned us in production, it is caching. The defaults changed in 15 and were tuned again in 16 — and every client project we took from staging to production had at least one 'why is this page serving stale data' incident.
What We Do Now On Every Project
- Read the revalidation behavior of every fetch before shipping — do not assume the default matches what you want
- Use { cache: 'no-store' } explicitly for user-specific data instead of relying on the default
- Tag-based revalidation (revalidateTag) for anything content-driven like blog posts or product catalogs — so our CMS can trigger a revalidation webhook on publish
- Avoid unstable_cache for now unless you have a concrete reason — the footgun-to-value ratio is still too high
Server Actions: Great for Forms, Risky for Everything Else
Server Actions feel like the future for form submissions. One function, no API route boilerplate, progressive enhancement works out of the box, and the DX for client-to-server data flow is excellent. We use them on every contact form and every admin mutation in client projects.
Where we stopped using them: public-facing mutations that need to scale, or anywhere we might want a third-party client (mobile app, partner integration) to hit the same endpoint later. For those, we still write proper API route handlers — partly because Server Actions are implicitly tied to the Next.js runtime, and partly because they do not compose well with rate limiting and request tracing in our stack.
Deployment: Vercel Is The Easy Path, And That's Fine
We have shipped Next.js 16 to Vercel, Netlify, AWS (via OpenNext), and self-hosted Node on a VPS. Our takeaways:
- Vercel is the frictionless path. Deploy-per-branch, preview URLs, image optimization, edge functions — everything works without configuration. For most client work, this is the correct default.
- Netlify is fine for static export with output: 'export'. If you need SSR, their Next.js runtime has improved dramatically in the last year but still lags Vercel on edge cases.
- OpenNext on AWS Lambda is viable if you have compliance reasons to stay on AWS, but budget 2 to 3 extra days for the setup compared to Vercel
- Self-hosted Node with a reverse proxy is simple, but you are now responsible for image optimization, request coalescing, and a build pipeline. Only worth it for specific reasons.
When We Still Do Not Reach for Next.js
Next.js is our default for most web work. But we do not use it for:
- Simple static brochure sites — plain HTML or Astro is lighter and cheaper to host
- Internal tools with mostly-interactive dashboards — Remix or plain React + Vite is often a better fit
- CMS-driven content sites where the client needs to edit pages — WordPress or a headless CMS + a simpler framework usually wins
- Anything where SEO does not matter and latency is dominated by API calls — a single-page React app is less overhead
Should You Upgrade If You're On 14 or 15?
If you are on 14, upgrade when you next have a two-week window of bandwidth. The migration is straightforward and the performance gains are worth it. If you are on 15, the 16 upgrade is smaller and you can probably do it in an afternoon on a well-tested codebase.
If you are still on the Pages Router on 13, this is a good moment to plan the App Router migration. The ecosystem has stabilized, the tooling for incremental migration works, and you will be dragging the Pages Router further into legacy territory every month you wait.
Building with Next.js and need an experienced team? → Talk to Us About Your Project
Top comments (0)