I remember the day I started using Next.js like it was yesterday. It was version 8. And honestly? It was love at first sight. I bootstraped our new project in Nextjs despite my CTOs hesitation and made my teammates who never wrote a single line of code in React, learn Nextjs and ship with confidence.
File-based routing.
SSR. SSG. ISR.
Zero config.
You slapped a file in the pages/
folder, and boom—you had a route.
Simple, elegant, almost… magical.
// pages/about.js
export default function About() {
return <div>About us</div>
}
It did what React should have done out of the box but didn’t. I was sold.
Deploy it, forget about webpack configs, no client-side routing hacks. Just productivity.
The Shift: Enter Next.js 13 & The App Router Madness
Then Next.js 13 hit, and things changed.
Suddenly, pages/
was optional. Enter the app/
directory. Layouts. Templates. Nested routing. React Server Components. use client
directives.
It felt… like betrayal.
// app/layout.js
export default function Layout({ children }) {
return <div className="layout">{children}</div>
}
Why?
Because the mental model shifted from “Page = Route” to “Segment = Route + Layout + Data Layer + Responsibility Split.”
Now I had to think in terms of route segments and where data should live: server component vs client component vs fetch cache vs what the hell.
The Mental Model Shift Nobody Talks About
Before, I thought:
“I add a file, it’s a route. Done.”
Now I have to ask:
- Is this a server component or client component?
- Should data fetching happen in
generateStaticParams
or inline in the component? - Where does this layout go?
- Is this a template or a layout?
It’s not just about writing code anymore.
It’s about architecting for Next.js’s new ecosystem.
// app/products/[id]/page.js
export default function ProductPage({ params }) {
const { id } = params
// Do I fetch here? Should this be a server component?
}
Fun, right?
Love, But With Conditions
Let me be clear: I love the power.
Server Components are a huge win.
Nested layouts? Clean.
Improved routing flexibility? Great.
Performance optimizations baked in? Finally.
But…
It feels overengineered.
Every simple use case now requires reading three different RFCs.
Constantly wondering if you’re doing it “the Next Way™” or just making a hack that’ll break in the next release.
Should You Care?
If you’re building large, scalable apps or deeply care about performance, yes.
Next.js App Router is awesome when you’ve got the bandwidth to understand it.
If you just want to ship stuff, fast and simple…
Stick to pages/
. Forget Server Components. Forget complicated layouts.
Use Next.js like the framework it used to be.
My Takeaway
Next.js is amazing at scale.
Next.js is terrible when you want simplicity.
It’s like loving a Swiss Army knife, but sometimes you just need a plain old screwdriver.
And now, the screwdriver has a dozen attachments you don’t care about.
Still, I’m in.
Because I know the payoff exists…
If I survive the learning curve.
Top comments (2)
I understand the frustration. Unfortunately—though I hope I’m wrong—this seems to be a common challenge when switching between frameworks.
For example, when I migrated an application from Nuxt 2 to Nuxt 3, it was easier to rewrite it from scratch than to do a direct migration. The same happened years ago when I moved a project from AngularJS to Angular.
Absolutely! But some of these changes don't seem to add much value