Choose Next.js when your React application has public pages that must load fast and rank in search, or when you want one TypeScript codebase that renders on the server and talks to your database directly. Choose plain React with Vite when the app lives behind a login, is used for long sessions and already has a separate backend API. Both are React; the difference is whether you want a server in the frontend.
What React and Next.js are today
React is a library for building user interfaces from components. It is now governed by the React Foundation under the Linux Foundation, having moved out of Meta's sole ownership in February 2026. The current release line is React 19; React 19.3 shipped in September 2026 with View Transitions and Fragment Refs promoted to stable.
React on its own does not decide routing, data loading or server rendering. The React documentation itself now recommends starting new apps with a framework (Next.js with the App Router, React Router, or Expo for native), and describes building from scratch with a build tool such as Vite as the path for apps whose constraints frameworks do not serve well.
Next.js, maintained by Vercel, is the most widely used of those frameworks. The current major version is 16; 16.3 was released in August 2026. New projects created with create-next-app use the App Router, TypeScript and Tailwind CSS by default, and Turbopack is the default bundler.
npx create-next-app@latest npm create vite@latest
How the App Router and server components work now
In the App Router, every component is a React Server Component unless the file starts with 'use client'. Server components run only on the server: they can read the database or call internal services directly, and their code is never sent to the browser. Client components handle state, event handlers and browser APIs. Server Actions let a form or button call a server function without you writing an API endpoint.
Caching has changed more than anything else. Earlier App Router versions cached aggressively and implicitly, which confused many teams. Since Next.js 16, the Cache Components model makes caching opt-in: dynamic code runs at request time by default, and you mark pages, components or functions as cacheable with the "use cache" directive. Next.js 16.3 added Instant Navigations, an opt-in set of features (including Partial Prefetching) aimed at making server-rendered apps feel as responsive as a single-page app, and the Next.js team has said these behaviours will become the default in a future major version.
// next.config.ts
const nextConfig = {
cacheComponents: true,
partialPrefetching: true,
};Two further changes worth knowing: middleware.ts has been renamed proxy.ts (the old name is deprecated), and params, cookies() and headers() must now be awaited. Next.js 16 requires Node.js 20.9 or later.
When we choose Next.js
- Public pages that must be found and must load fast. Product listings, marketplace pages, documentation and SaaS marketing sites with a logged-in area.
- A TypeScript team that wants one codebase. Server components and Server Actions remove the need for a separate API for simple reads and writes.
- Mixed static and dynamic content. Static shells with dynamic, personalised parts streamed in is exactly what Cache Components is designed for.
- Customer portals over an existing backend. Next.js can call Odoo's JSON-2 API or your own services from the server, so API keys never reach the browser.
When plain React with Vite is the better choice
A client-rendered React app built with Vite is a folder of static files and a JavaScript bundle. There is no frontend server to run, scale or patch. For many business tools that is the whole appeal.
- Internal tools and dashboards. Users log in, keep the tab open all day and never arrive from a search engine. Server rendering buys little here.
- A backend already exists. If Django, FastAPI, Node.js or Odoo already serves a clean API, a second server layer in Next.js duplicates authentication and error handling.
- Offline or near-offline use. A client-rendered app with a service worker and local storage is simpler to make work without a network than a server-first app.
- Embedding. Widgets inside another product or an Odoo view are easier as client bundles.
- Hosting constraints. Static files can sit on any CDN or behind a customer's own web server, which matters for on-premise deployments.
The price is that you assemble the pieces yourself: a router (React Router or TanStack Router), a data-fetching library, and form handling. That is a well-trodden path, but it should be a decision rather than an accident.
| Question | Next.js (App Router) | React + Vite SPA |
|---|---|---|
| Public pages need SEO and fast first load | Strong fit | Weak without extra work |
| Logged-in tool used for long sessions | Works, adds a server | Strong fit |
| Separate backend API already exists | Adds a second server layer | Strong fit |
| Hosting | Node.js runtime or a platform that supports Next.js | Any static host or CDN |
| Learning curve | Server/client split, caching model | Plain React, choose your own libraries |
| Security surface | Frontend server with server code | Static files; security lives in the API |
Where teams go wrong with React
- Picking Next.js by reputation for an internal tool. Then fighting hydration errors and caching rules on pages nobody will ever search for.
- Marking everything
'use client'. This keeps the server's cost while losing its benefit. Keep data loading in server components and push interactivity to small client leaves. - Putting business logic in the frontend. Pricing, tax (including GST) and permission rules belong in the backend or ERP, whichever framework renders the page.
- Following old tutorials. Guidance written for the Pages Router, for implicit App Router caching or for Create React App is now out of date. Check the version on anything you copy.
If you are still choosing a framework family, Angular vs Vue vs Svelte covers the alternatives, and choosing a web application stack puts all of it in order. The backend side comes next in Django vs FastAPI vs Node.js.
Questions we get asked
Should I use Next.js or plain React for a new project?
Use Next.js when you have public pages that need search visibility and a fast first load, or when you want one TypeScript codebase that renders on the server and reads data directly. Use plain React with Vite for logged-in tools, dashboards and apps that already have a separate backend API, because it deploys as static files with no frontend server to run or patch.
What are React Server Components?
React Server Components are components that run only on the server. They can read a database or call internal services directly, and their code is never sent to the browser, which reduces the JavaScript a page ships. In the Next.js App Router every component is a server component by default, and files that need state or event handlers opt in to the client with the 'use client' directive.
Does Next.js still cache everything by default?
No. Since Next.js 16 introduced Cache Components, caching is opt-in: dynamic code in pages, layouts and route handlers runs at request time unless you mark it with the "use cache" directive. You enable the model with cacheComponents in next.config. Older App Router guidance describing implicit caching no longer reflects how new Next.js projects are meant to work.
Is Create React App still recommended?
No. React's documentation now recommends starting with a framework such as Next.js or React Router, and, for building from scratch, a build tool such as Vite, Parcel or Rsbuild. For a client-rendered React app today, Vite is the usual choice: run npm create vite@latest and pick the React template, then add a router and a data-fetching library.