Cilantrobyte.

Journal · Engineering

Next.js App Router after a year of production use

What we got right, what we got wrong, and what we'd tell our past selves before reaching for it again.

Dec 3, 2025·11 min read·By Theo Whitfield

We shipped our first production Next.js App Router project in December 2024. It is now a year later and we have shipped six more. Here is what we would tell ourselves a year ago.

First: Server Components are great, and we were too cautious about using them. Most of our "use client" boundaries could have been pushed deeper into the tree. The rule we arrived at eventually is: interactive leaf components are client; everything else is server until proven otherwise.

Second: data fetching in the App Router is better than it looks from the docs. Fetch on the server, use React cache for de-duping, and for the love of everything stop prop-drilling data through five layers when you could just re-fetch it closer to where it is used. The performance is fine; the readability is dramatically better.

Third: Route Handlers are not the Express replacement you want them to be. For anything beyond simple JSON endpoints, we still reach for a real backend. Route Handlers are great for webhooks and small data APIs, but do not try to build a complete application on them.

Fourth: the bundler story is still unsettled. Turbopack is much faster for dev, production builds are still webpack-adjacent, and the cut-over keeps getting pushed. Plan your build infrastructure with the assumption that things will change.

Fifth, and most important: the App Router is worth the migration if you are building something new. It is probably not worth the migration if you have a working Pages Router app. The incremental adoption path exists but is painful.

We will keep shipping with it. We will also keep warning clients that the documentation is six months behind the code.