The gap React leaves on the floor
React ships a component model and a renderer. It does not ship routing, server rendering, data fetching conventions, code splitting, build tooling, or deployment. Every React-only app reinvents those pieces from npm packages and glue code, and then maintains the glue forever.
What you end up wiring by hand
- Routing — React Router or TanStack Router, plus a strategy for nested layouts.
- Server rendering — SSR setup, hydration boundaries, streaming.
- Data fetching — where, when, how to cache.
- Code splitting — dynamic imports, prefetch, chunking.
- Build tooling — Vite/Webpack/Turbopack config, env loading, source maps.
- Deployment — static vs Node server vs edge runtime.
Why a framework wins for app work
The React team itself now recommends starting with a framework. Standalone Create React App was retired specifically because the gap above kept biting beginners. Next.js fills the gap with conventions: file-system routing, Server Components by default, fetch-with-caching primitives, image/font/script optimizers, and a production server that runs anywhere Node runs.
Where this lesson lands
You'll build everything from this point on under those conventions. When something feels surprising later (params is a Promise, fetch isn't cached, components render on the server), remember the trade: you stop owning the wiring; in exchange you accept the framework's opinions.
Reach for Next.js when the product needs routing, server rendering, data and cache conventions, build integration, and deployment behavior to form one maintained contract. React remains the component and rendering layer; the framework earns its cost by owning the seams around that layer. A framework is not automatically better because it has more features. Its conventions reduce repeated integration decisions, but they also constrain file placement and execution. A small embedded widget or client-only screen may need React without inheriting the rest of the framework.
Build the same small requirement with React alone and with Next.js conventions. Compare the decisions and owners for routing, server rendering, data, bundling, and deployment, then ask whether a new teammate can discover those contracts from the project itself.