Skip to main content
ASoc
Tutorial

Is Next.js Better Than React? It's React Plus the Parts You'd Build

Next.js is React plus a router, build and server rendering. Measured on this repo: 884 prerendered pages, and a client FAQ whose text is still in the HTML.

The ASoc Team6 min read

Next.js is not better or worse than React, because it is React plus the parts React leaves out: a router, a build, server rendering and metadata. Pick it when the page must be found by search engines or needs a server; skip it when the app lives behind a login. This storefront runs React 19.2.4 on Next.js 16.2.9 and prerenders 884 pages from one npm run build.

The question has a hidden premise

"Better than React" treats the two as rivals. They are layers. React renders components. Next.js is a framework that installs React, then decides how those components become URLs, HTML and JavaScript. Every Next.js page you write is a React component, and removing Next.js does not remove React; it removes the decisions Next.js made for you.

So the real question is: do you want to make those decisions yourself?

DecisionPlain React (with a bundler such as Vite)Next.js
RoutingYou add and configure a router libraryFile system: src/app/pricing/page.tsx is /pricing
First HTML sentAn empty shell, filled in by JavaScriptFull HTML, prerendered at build or on request
Page titles, OG imagesYou add a head-management librarymetadata exports and opengraph-image.tsx files
Data loadinguseEffect plus a fetch libraryasync Server Components, Server Actions
Backend endpointsA separate serverRoute handlers in the same project
Sitemap and robotsA script you writesitemap.ts and robots.ts
Upgrade pathYou own every library choiceOne framework version to move

Plain React wins on flexibility and on having nothing you did not choose. Next.js wins on how much you do not have to build.

What Next.js gave this codebase, file by file

These are the parts of the storefront that exist only because the framework provides a slot for them.

FileWhat it doesReact alone would need
src/app/sitemap.tsEmits every product, hub and blog URL with a declared lastModifiedA custom build script
src/app/robots.tsGenerates robots.txtA static file kept in sync by hand
src/app/blog/[slug]/opengraph-image.tsxRenders a social card per postAn image service or a pre-build step
src/app/api/webhooks/lemonsqueezy/route.tsReceives signed payment webhooksA separate Node server
src/proxy.tsRefreshes the session on every requestServer middleware elsewhere

Counting what a build produces is the cleanest way to see the difference. Running npm run build here ends with:

✓ Generating static pages using 3 workers (884/884) in 8.0s

That is 884 real HTML files. A plain React single-page app would ship one index.html and let the browser assemble the rest.

Client-side interactivity still works the same

Choosing Next.js does not make the page less interactive. The FAQ accordion on /pricing is src/components/molecules/FaqItem.tsx, a normal React component with useState:

"use client";
import { useId, useState } from "react";
// ...
export default function FaqItem({ question, answer }: FaqEntry) {
  const [open, setOpen] = useState(false);

It is a Client Component, yet its question text is already in the prerendered file. After the build, grep -c "Is this really a one-time payment" .next/server/app/pricing.html returns 1. Crawlers read the question without running JavaScript, and the browser then hydrates the same component so the click handler works. That combination, server HTML plus client behaviour from one component, is the main thing a plain React shell cannot give you.

Only 26 of the 126 .tsx files under src/components and src/app carry "use client"; the rest never ship their code to the browser as client components.

When plain React is the better choice

SituationBetter fitWhy
Admin tool behind a login, no SEO needReact + ViteThere is nothing for a crawler to read, so prerendering buys little
Widget embedded in someone else's pageReactYou ship a bundle, not a site
Team already has a router, data layer and deploy pipelineReactA migration would cost more than it returns
Marketing site, store, blog or docsNext.jsSearch visibility and fast first paint decide revenue
App needing both public pages and a dashboardNext.jsOne project, static public routes, dynamic private ones

For an admin dashboard in particular, see Next.js vs React + Vite for admin dashboards. For the migration direction, Next.js vs Create React App covers what moving costs.

What you pay for the framework

Being honest about trade-offs matters, because "Next.js is better" is only true if you accept these.

  • A mental model to learn. The Server/Client Component boundary is the main one. React use client lists the 26 files here that needed the directive and why.
  • Constraints on what runs where. Browser APIs such as window cannot run during prerender. A component that touches them has to be a Client Component and guard its access; forcing client-side rendering shows what each option emits.
  • A framework upgrade is yours to schedule. The repo's CLAUDE.md warns that this Next.js version is newer than most training data, so the bundled docs in node_modules/next/dist/docs/ are the reference, not memory.

Mistakes and troubleshooting

SymptomCauseFix
"You're importing a component that needs useState" at buildA Server Component imports hook-using codeAdd "use client" to the file that owns the hook
window is not defined during buildBrowser API read while prerenderingRead it inside useEffect, or guard with typeof window
Page content missing from view-sourceData fetched in useEffect after loadFetch in a Server Component so it is in the HTML
Everything is a Client Component and the bundle grew"use client" placed on a parent instead of the leafPush the directive down to the smallest interactive file
Metadata missing on a client pagemetadata export is not allowed in a Client ComponentExport it from the server page.tsx that renders the client part

Frequently asked questions

Is Next.js better than React for SEO? For pages that must rank, yes in practice: Next.js sends finished HTML, so a crawler sees content without executing JavaScript. React alone can do this only if you add your own server rendering.

Do I need to learn React before Next.js? Yes. Every Next.js page is a React component, so state, props and Hooks carry over directly. What you add is routing, rendering modes and the Server/Client split.

Can I use React libraries in Next.js? Mostly. Libraries that use state, effects or browser APIs need to be imported from a Client Component. Pure-render libraries work anywhere.

Is Next.js slower than React? Not inherently. First paint is usually faster because HTML arrives already rendered. Hydration still has a cost, which is why keeping "use client" to the leaves matters.

Templates in this post

ASoc Folio is a personal portfolio site for designers and developers with services, resume and filtered work. ASoc Forge is an AI resume-builder landing page with a live editor preview. ASoc Frame is an AI image-generator landing page with a prompt hero and a how-it-works flow.

Keep reading

Tutorial10 min read

The Next.js Bundle Analyzer Doesn't Run on Turbopack. Here's What Does.

ANALYZE=true writes nothing in Next 16, and the route table no longer prints First Load JS. The replacement, where it hides its output, and the 42 KB one constant was costing twelve routes.

Read more
Tutorial7 min read

A Next.js Calendar Grid, and the Timezone Bug It Has to Avoid

No calendar UI here, but this codebase already fixed the timezone bug that breaks most of them, twice. The UTC-safe date pattern, applied to a month grid.

Read more