tl;dr
Most indie devs should choose Next.js, not plain React. React is still inside that choice anyway. Standalone React only makes sense when you truly want a client-only app or very custom architecture.
Tool
Next.js
A full React framework with routing, server rendering, APIs, and production defaults built in.
- Pricing
- Free and open source.
- Best for
- Builders who want a complete, SEO-friendly React stack without assembling every layer by hand.
Tool
React
The UI library itself, without routing, rendering strategy, or framework-level defaults.
- Pricing
- Free and open source.
- Best for
- Developers who intentionally want to choose and compose the rest of the stack themselves.
verdict
At a glance
A quick read on where each tool wins before you dive into the details.
| Dimension | Next.js | React | Edge |
|---|---|---|---|
| Out-of-the-box capability | Routing, SSR, API routes, metadata, and deployment patterns come built in. | You get components and hooks, then you choose the rest yourself. | Next.js |
| Flexibility | Flexible, but within framework boundaries. | Maximum control because it is just the library. | React |
| SEO readiness | Much easier for public-facing sites and content-heavy products. | Possible, but you need more setup. | Next.js |
| Complexity for solo founders | Lower because key decisions are already made. | Higher because the missing pieces become your problem. | Next.js |
| Usefulness for app shells and widgets | Great, but heavier than necessary for some cases. | Excellent if you only need a client-side application shell. | React |
This comparison is fundamentally weird
We need to address the elephant in the room: Next.js is React. Choosing Next.js means choosing React. You are not picking between two competing libraries. You are deciding whether to use React bare or React with a full production framework built around it.
That is why this comparison feels strange every time someone writes it up. It is like comparing "driving" to "driving a Toyota." One is the activity, the other is a specific way of doing it.
But people search for this all the time. And honestly, it is a fair question. Because "plain React" in 2026 looks very different from "Next.js" in 2026, and the decision has real consequences for how you build, deploy, and maintain your product.
So let us answer it properly.
What "plain React" actually means in 2026
When we say "plain React," we do not mean Create React App. That project is dead. Officially deprecated. If someone recommends CRA in 2026, close that blog post immediately.
Plain React in 2026 means Vite as your build tool, plus whatever you bolt on yourself. That typically looks like:
- Vite for bundling and dev server (fast, reliable, well-maintained)
- React Router or TanStack Router for client-side routing
- TanStack Query or SWR for data fetching
- Manual SSR setup if you need it (most people skip this entirely)
- Full control over your build pipeline, deployment target, and folder structure
This setup is genuinely good. Vite's dev server is fast. Hot module replacement works well. The ecosystem around client-side React is mature and battle-tested.
The tradeoff is that you are assembling the stack yourself. Every dependency is your choice, your integration work, and your maintenance burden. That is either freedom or overhead depending on your temperament and project needs.
What Next.js gives you on top
Next.js takes React and wraps a production-ready framework around it. Here is what you get out of the box that you would otherwise build or configure yourself:
File-based routing. Drop a file in app/dashboard/page.tsx and you have a route. Layouts nest automatically. Loading states and error boundaries are built into the file convention. No router config files.
Server Components. This is the big one. React Server Components let you fetch data and render HTML on the server without shipping that code to the client. Your bundle gets smaller. Your initial page loads get faster. The mental model takes getting used to, but the performance wins are real.
Server Actions. Form submissions and mutations that run on the server, called directly from your components. No API route boilerplate for basic CRUD operations. It feels weird at first, then it feels obvious.
ISR (Incremental Static Regeneration). Static pages that revalidate in the background on a schedule you control. You get CDN-speed page loads with data that stays reasonably fresh. This is hard to replicate outside Next.js without serious infrastructure work.
Image optimization. The next/image component handles responsive sizing, lazy loading, format conversion (WebP/AVIF), and CDN caching. You can do this yourself with other tools, but Next.js makes it a one-line change.
Metadata API. SEO tags, Open Graph images, structured data. The generateMetadata function lets you build dynamic meta tags colocated with your page logic. Way cleaner than wrestling with react-helmet or equivalent.
Middleware. Run code at the edge before a request hits your page. Authentication checks, redirects, geolocation-based routing, A/B testing. It runs on the CDN edge, not your server.
Built-in API routes. Need a quick webhook endpoint or a server-side proxy? Drop a route.ts file in your app directory. Not a replacement for a real backend, but good enough for many indie products.
That is a lot of built-in capability. And importantly, it all works together. The routing knows about the server components which know about the data fetching which knows about the caching. Integration is the product.
When plain React still makes sense
Not every project needs what Next.js offers. Here are the cases where plain React with Vite is the better call:
Single-page applications behind a login. If your entire app lives behind authentication and no public page needs to be indexed by Google, SSR gives you nothing. A Vite SPA is simpler, faster to build, and has fewer moving parts.
Embedded widgets. Building a React component that gets embedded in other people's sites? You want a minimal bundle with zero framework overhead. Next.js is overkill here.
Electron and desktop apps. Electron apps run in a browser shell. There is no server. No SEO. No routing conventions that make sense for desktop UIs. Plain React with Vite is the standard approach.
Internal tools and admin dashboards. Your company's internal CRM does not need server-side rendering. It does not need ISR. It needs fast client-side navigation and good state management. Vite + React Router + TanStack Query is a perfect fit.
Browser extensions. Extensions run in a sandboxed browser environment. Next.js's server-side features are irrelevant. You need a lightweight React build that produces static assets.
Micro-frontends. If you are composing multiple independently deployed frontend apps, each one needs to be self-contained. A framework like Next.js adds coordination overhead between micro-frontends that you probably do not want.
The common thread: plain React wins when you do not need a server, do not need SEO, and do not want framework opinions getting in the way of a specific architectural requirement.
The framework tax
Next.js is not free in the "no tradeoffs" sense. Choosing it means accepting certain opinions:
File-based routing is mandatory. You cannot opt out. If you have strong opinions about how routing should work, or if your URL structure does not map cleanly to a file tree, you will fight the framework.
The App Router is complex. Server Components, client components, the "use client" directive, server actions, caching behavior, streaming, partial prerendering. The mental model has a real learning curve. The React documentation and Next.js documentation sometimes disagree on best practices, which does not help.
Build times grow. As your app gets bigger, Next.js builds get slower. Type checking, linting, server component compilation, static page generation. A large Next.js project can have five-to-ten-minute builds. A Vite SPA of the same complexity might build in thirty seconds.
Vercel-optimized defaults. Next.js works on other platforms (Docker, AWS, Cloudflare), but the smoothest experience is on Vercel. Edge functions, ISR, image optimization, and analytics all work best on Vercel's infrastructure. Self-hosting Next.js is doable but requires more configuration.
Upgrading between major versions is work. The Pages Router to App Router migration was painful for many teams. Next.js moves fast, and keeping up means periodic migration effort.
None of these are dealbreakers. But they are real costs you should factor into your decision, especially if you are a solo founder who does not want to debug framework internals at 2 AM.
Performance considerations
Performance is nuanced here because the two setups optimize for different things.
Plain React with Vite is blazing fast for SPAs. The dev server starts in milliseconds. Hot module replacement is near-instant. Production builds are small because there is no server runtime. Client-side navigation is fast because everything is already loaded. The weakness is initial page load on slow connections and SEO for public pages.
Next.js optimizes for first meaningful paint and server-rendered content. Server Components reduce client-side JavaScript. ISR gives you static-site speeds with dynamic data. But there is server overhead, cold start latency on serverless platforms, and more complexity in the caching layer.
For a public-facing SaaS with a marketing site, blog, and documentation alongside the app, Next.js performance wins are significant. For a dashboard that users visit daily behind a login, the SPA model is hard to beat on perceived speed after the first load.
The hiring angle
Here is something that does not get discussed enough: the job market has effectively merged "React developer" and "Next.js developer."
Look at job postings for frontend roles. Most React positions now list Next.js as a requirement or strong preference. Most React tutorials and courses teach Next.js as the default way to build with React.
If you are building a team (even a small one), choosing Next.js means a larger hiring pool. Developers expect it. It is the default mental model for how React apps get built in 2026.
If you choose plain React with a custom Vite setup, you will need developers who are comfortable assembling and maintaining their own framework-like layer. Those developers exist, but they are a smaller pool and they tend to be more senior (and more expensive).
Migration path
"We will start with plain React and move to Next.js later if we need to."
We hear this a lot. It is technically possible but more expensive than people expect.
Moving from a Vite SPA to Next.js means rethinking your routing, your data fetching patterns, your component boundary between server and client, and your deployment infrastructure. It is not a weekend project for any non-trivial app.
Going the other direction (Next.js to plain React) is even harder because you are removing capabilities your code depends on.
Our advice: make the framework decision early and commit to it. The switching cost is real.
When to choose Next.js
- You are building a product with public-facing pages that need SEO
- You want server-side rendering or static generation without setting it up yourself
- You need a blog, docs site, or marketing pages alongside your app
- You want a single deployment that handles both your frontend and lightweight API routes
- You value convention over configuration and want decisions pre-made
- You are a solo founder or small team and want fewer integration decisions
- You plan to deploy on Vercel, Netlify, or a platform that supports Next.js natively
When to choose plain React
- Your app is entirely behind authentication with no public SEO needs
- You are building an embedded widget, browser extension, or Electron app
- You want maximum control over your build pipeline and deployment target
- You are building an internal tool or admin dashboard
- You have strong architectural opinions that conflict with Next.js conventions
- Build speed is a top priority and you cannot tolerate multi-minute builds
- You are working within a micro-frontend architecture
Final verdict
Most new projects should start with Next.js. It is not even close.
The amount of production-grade infrastructure you get for free (routing, server rendering, image optimization, metadata, API routes, middleware) would take weeks to assemble and months to maintain if you did it yourself.
Plain React with Vite is a great choice when you have a specific reason for it. SPAs, embedded widgets, Electron apps, internal tools. These are legitimate use cases where Next.js adds complexity you do not need.
But if you are starting a new SaaS, a content site, or any product with public-facing pages, pick Next.js, set up your project, and focus on building the thing that actually matters: your product. The framework decision should take five minutes, not five days.
Related alternatives
FAQ
Is Next.js better than React?+
That question is slightly broken because Next.js uses React. The real question is whether you want React plus a framework or React by itself.
When is plain React still the right choice?+
When the app is client-only, embedded, or intentionally custom enough that you want to choose every major piece yourself.
What would we recommend to most indie builders?+
Next.js. It removes too many common setup decisions to ignore.