Why Next.js Exists: The Problems Plain React Doesn't Solve
Create React App gives you a blank canvas and zero opinions on routing, data fetching, or SEO. A real production app needs answers to all three.
React, by design, is unopinionated about routing, data fetching, and rendering strategy. That's a genuine strength for a library — and a genuine gap for anyone trying to ship a real production app, who now has to make and maintain several non-trivial architectural decisions before writing a single feature. Next.js exists to close that specific gap.
Problem 1: plain React ships blank HTML
A plain Create-React-App-style app's initial HTML is essentially `<div id="root"></div>` — the entire page renders after JavaScript downloads, parses, and executes in the browser. That's a real cost for both a slow connection (nothing meaningful paints until JS runs) and for SEO (a crawler that doesn't fully execute JavaScript sees an empty page). Next.js's answer is rendering HTML on the server before it ever reaches the browser — the actual subject of the next post in this series.
Problem 2: routing is a real, unsolved decision in plain React
Plain React has no router. You pick one (React Router, historically), configure it, and now own keeping route definitions, code-splitting per route, and layout nesting all working together — none of it free. Next.js's file-based routing (a file at `app/blog/[slug]/page.tsx` IS the route, no separate route-config file to keep in sync) removes an entire category of "did I register this route correctly" bugs, and ties routing directly to code-splitting and layouts by construction, not by additional configuration.
Problem 3: performance optimizations that are easy to skip
Image optimization (correct sizing, lazy loading, modern formats), font loading without layout shift, and JavaScript code-splitting per route are all things a plain React app *can* do — with real, ongoing engineering effort most teams under-invest in. Next.js makes several of these the default behavior (`next/image`, `next/font`) rather than an opt-in optimization someone has to remember to implement and maintain.
The honest framing
Next.js isn't "better than React" — it's React, plus opinionated, production-tested answers to the questions plain React deliberately leaves open. That's a real tradeoff (less flexibility, a framework's release cycle to track) in exchange for not re-solving routing, rendering strategy, and performance basics on every project from scratch. This site runs on it for exactly that reason.