The Short Answer
Use Next.js for anything that will be publicly indexed, needs fast initial load, or will run in production. Use plain React (via Vite) for internal tools, dashboards, or prototypes where SEO doesn't matter.
That's it. The rest of this post is the reasoning.
What Next.js Adds on Top of React
Next.js is a React framework — all Next.js apps are React apps, but not all React apps use Next.js.
The key additions: server-side rendering out of the box, static generation, file-based routing, API routes, an Image optimisation component, and SEO-friendly defaults that you'd otherwise piece together by hand.
With plain React (Vite setup), you get a blank canvas. No routing until you add React Router. No SSR unless you wire it yourself. No image optimisation, no middleware, no built-in API layer. That's fine for certain use cases — but for anything with a homepage that needs to rank on Google, you're reinventing wheels that Next.js ships by default.
To put numbers on it: a plain Vite React app typically sends 150–300 KB of JavaScript to the browser before users see any meaningful content. Next.js with server components can reduce the client-side bundle to under 50 KB for the same page, because component rendering happens on the server and only interactive pieces cross the wire as JavaScript. On a 4G mobile connection, that difference is visible — roughly 1.5 seconds vs 0.4 seconds on a typical marketing page.
Next.js App Router (Next.js 13+)
The App Router, stable since Next.js 13 and the default in Next.js 15, uses React Server Components. Pages render on the server by default — only components explicitly marked with "use client" run in the browser.
This gives faster time-to-interactive (less JavaScript sent to the browser), better SEO (content rendered in HTML, not JavaScript), and simpler data fetching with async/await directly in components.
In practical terms: a product listing page that used to require useEffect + a loading state + a spinner now just uses async directly in the component. You write this:
// Next.js 15 App Router — no useEffect, no loading state wiring
export default async function ProductsPage() {
const products = await fetchProducts();
return <ProductList items={products} />;
}
Instead of the old pattern of setting up a useEffect, managing isLoading state, and handling the flash of empty content. The App Router removes an entire class of bugs — specifically, the ones where data arrives after the component mounts and the page jumps around.
The tradeoff: you now have to think about where each component runs. A component that uses useState, useEffect, browser APIs, or event handlers must be marked "use client". Forgetting this is the single most common mistake teams make when adopting the App Router.
When to Choose Next.js
- Marketing sites, landing pages, and blogs where SEO is critical
- E-commerce where product pages need to be indexed
- SaaS applications needing both public pages and authenticated dashboards
- Any app where you care about Core Web Vitals and page speed scores
Concrete scenario — professional services firm: A 14-person accounting firm in Chicago needed a website that could rank for local searches like "CPA firm Chicago small business." Their developer quoted them a plain React build. The result: Google's crawler saw a blank page on first render, because React hydration hadn't completed. Six months after launch, they ranked for nothing. They rebuilt in Next.js with static generation for service pages and SSR for a contact form. Within four months, three pages landed on page one. The underlying service didn't change — only the rendering strategy did.
Concrete scenario — SaaS product: A B2B SaaS startup with a public marketing site and a logged-in dashboard mixed both in a single Next.js codebase. Public pages use static generation (blazing fast, served from CDN). The dashboard uses client-side rendering behind authentication. One framework handles both without stitching together two separate repos.
When Plain React Is Fine
- Internal admin dashboards with no public SEO requirements
- Single-page tools accessed only by authenticated users
- Rapid prototypes where Next.js conventions get in the way more than they help
Concrete scenario — internal operations tool: A 30-person logistics company in Manchester needed a dispatch dashboard: real-time driver locations, job assignment, shift management. Nobody outside their staff would ever open it. Google would never index it. Their developer built it with Vite + React + React Query. Setup took an afternoon. No SSR configuration, no route-group conventions, no server action debates. The team shipped in six weeks and the tool works exactly as needed.
If that same team had chosen Next.js, they'd have spent the first two weeks making decisions that don't affect their outcome — whether to use the Pages Router or App Router, how to handle authentication with middleware, where server actions fit in. None of that work would have made the dispatch dashboard better.
Next.js vs Plain React — Side-by-Side
| Factor | Next.js (App Router) | Plain React (Vite) |
|---|---|---|
| SEO & crawlability | Excellent — HTML rendered server-side | Poor out of the box — requires extra config |
| Initial page load speed | Fast — minimal JS to client | Slower — full bundle sent upfront |
| Routing | Built-in file-based routing | Manual (React Router or similar) |
| API layer | Built-in Route Handlers | Separate backend needed |
| Image optimisation | Built-in <Image> component | Manual (third-party or DIY) |
| Learning curve | Higher — Server vs Client Components | Lower — standard JS/React |
| Best for | Public sites, SaaS, e-commerce | Dashboards, internal tools, prototypes |
| Build time complexity | Higher for large static sites | Low |
| Hosting flexibility | Node server or edge (Vercel, Netlify, AWS) | Any static host |
| Bundle size (typical) | 30–80 KB client JS | 150–400 KB client JS |
What to Expect in Practice
Choosing Next.js doesn't mean your project is automatically faster or better. The framework gives you the tools — you still have to use them correctly.
Data fetching patterns matter. Moving a useEffect data fetch into a Server Component speeds things up. But if you put that same fetch inside a Client Component (because you reached for "use client" without thinking), you get none of the benefit. Teams new to the App Router often do this and wonder why performance hasn't improved.
Deployment is not automatic. Next.js with Server Components needs a Node.js environment or an edge runtime. You cannot drop it onto a basic shared hosting account. Vercel is the path of least resistance. AWS App Runner, Railway, Render, and Fly.io all work. A basic VPS works too, but you need to manage the Node process yourself. Budget 1–3 days for deployment setup on your first Next.js project if you're self-hosting.
Caching is powerful and confusing. Next.js 15 changed the caching defaults significantly compared to Next.js 13–14. Data is no longer cached by default — you opt in to caching explicitly. If your team is following App Router tutorials written before 2025, the caching behavior they describe may not match what your app actually does. Read the current docs, not old blog posts.
Authentication adds complexity. Protecting routes in Next.js requires middleware — a small edge function that checks session cookies before the page renders. Libraries like NextAuth (Auth.js) and Clerk handle this well, but they each have their own conventions. Plan for a full day of setup if authentication is new to your Next.js project.
One Honest Note
Next.js isn't free. The App Router has a real learning curve — Server vs Client Components catches every team out the first time. If you don't actually need SSR or SEO, you're paying that complexity tax for nothing. We've seen teams choose Next.js for an internal dashboard "just in case" and spend weeks fighting the framework instead of shipping. Pick the simpler tool when you can.
Common Mistakes
Using Next.js for purely internal tools. We see this regularly. A startup builds an employee-facing admin panel in Next.js because "that's what everyone uses now." Three sprints later they're debugging middleware and server actions for a page that 12 people use internally. Vite would have shipped in a third of the time.
Ignoring the Pages Router entirely. The App Router is the future, but if your team already has a large Pages Router codebase, migrating it incrementally is valid — the two can coexist in the same project. Don't rebuild a working app just to use the newest syntax.
Fetching data client-side in Server Components. Some developers add "use client" to almost every component out of habit, which defeats most of the App Router's advantages. Audit your component tree: any component that only displays data (no state, no events) should stay a Server Component.
Skipping error boundaries. Next.js provides error.tsx files that act as error boundaries per route segment. Teams often forget to add these and end up with white screens when a server fetch fails in production. Add an error.tsx to every major route group.
Misreading hosting costs. Serverless deployments on Vercel can incur unexpected costs at scale — each page request can trigger a serverless function invocation. A static export (output: 'export') eliminates this but removes SSR. Know which rendering mode each route uses before you go live.
Related guides
- How to build a web app with Next.js in 2026
- Web developer in Rajkot: building AI-powered web apps
- Freelance web developer in India for startups and agencies
- Web development in Rajkot: what to expect
- Our web development services
The Bottom Line
In 2026, Next.js is the default for production React web development. The App Router makes SSR and SSG straightforward without manual setup complexity. The only reason to skip it is if your app genuinely has no public pages — in which case skip it.
Talk to us if you want a second opinion on which fits your project — we'll tell you honestly when plain React is the better call.
Frequently Asked Questions
Is Next.js always faster than plain React?
Not automatically. Next.js gives you the architecture to achieve faster page loads through server rendering and smaller client bundles, but you have to use it correctly. A poorly implemented Next.js app with unnecessary "use client" directives and client-side data fetching can be slower than a well-built Vite React app. The framework provides the tools; the outcome depends on how you use them.
Can I use Next.js for a project that has both a public website and a private dashboard?
Yes, and this is one of Next.js's strongest use cases. Public routes (homepage, pricing, blog) can use static generation and render near-instantly from a CDN. Protected routes (the logged-in dashboard) render client-side behind authentication middleware. A single codebase, one deployment, two rendering strategies. Libraries like Clerk or Auth.js handle the authentication layer cleanly.
Do I need Vercel to run Next.js?
No. Vercel is the easiest deployment path because it's built by the same team, but Next.js runs on any Node.js host. AWS (EC2, App Runner, Lambda), Railway, Render, Fly.io, and DigitalOcean App Platform all support it. You can also self-host on a VPS with a Node process manager like PM2. The only limitation is that static export mode (output: 'export') removes server-side features, so you'd lose SSR and API routes if you go fully static.
What is the difference between the Pages Router and App Router?
The Pages Router is the original Next.js routing system (pre-Next.js 13). Each file in /pages becomes a route. Data fetching uses getServerSideProps and getStaticProps. The App Router (Next.js 13+, default in Next.js 15) uses the /app directory and React Server Components. Data fetching uses async/await directly in components. The App Router is the current recommended approach for new projects. Existing Pages Router codebases can migrate gradually — both routers can coexist.
How long does it take to learn Next.js if you already know React?
For basic routing and static pages: one to two days. For understanding Server Components vs Client Components well enough to make deliberate decisions: one to two weeks of building something real. For caching strategies, middleware, and production deployment: figure on a full project cycle before it feels natural. The official Next.js Learn course (free, at nextjs.org/learn) covers the fundamentals in roughly eight hours and is worth doing before starting a client project.
What is the real cost difference between building in Next.js vs plain React?
Initial development takes 10–20% longer in Next.js for teams new to the App Router, because of the Server vs Client Component mental model and deployment setup. After the first project, the overhead mostly disappears. Long-term, Next.js projects tend to cost less to maintain for public sites because performance problems surface earlier (Lighthouse and Core Web Vitals are harder to ignore when your build process flags them) and the built-in image and font optimisation prevents a class of performance debt. For internal tools, the equation reverses — plain React is cheaper to build and maintain.
Should I use Next.js or React Native for a mobile app?
These are different tools for different platforms. Next.js builds web applications that run in browsers. React Native builds native iOS and Android applications. If you need a mobile app, use React Native (or Expo, which wraps it). If you need a web app that works well on mobile browsers, use Next.js. Some teams build both and share business logic and component libraries between them — that's a valid architecture, but it requires planning from the start.
