React vs Next.js comes up in nearly every kickoff call we have with a new client. Both names get thrown around interchangeably by people who read one blog post, and that confusion leads to wrong technology picks that cost real money six months later. Here is the actual difference, not the marketing version.
What React Actually Is
React is a JavaScript library, not a framework. It gives you a way to build user interfaces out of reusable components and it manages state and re-rendering for you. On its own, React does not decide how your app gets to the browser, how routing works, or how data gets fetched. In a plain React setup (built with Vite or Create React App historically), the browser downloads a nearly empty HTML file plus a JavaScript bundle, then React runs in the browser to build the page. This is client-side rendering (CSR): all the rendering work happens on the visitor's device, after the JS has loaded and executed.
That architecture is why React became the default choice for single-page applications (SPAs) — dashboards, internal tools, admin panels, and web apps where the user is logged in and interacting with data rather than reading content.
What Next.js Actually Is
Next.js is a framework built on top of React. It adds the pieces React deliberately leaves out: file-based routing, image optimization, API routes, and most importantly, rendering strategies beyond CSR. With Next.js you can choose server-side rendering (SSR, HTML generated per request on a server), static site generation (SSG, HTML generated once at build time), incremental static regeneration (ISR, static pages that refresh on a schedule), or React Server Components (RSC, the newer App Router model where components run on the server by default and ship less JavaScript to the browser).
In short: React is the UI layer, Next.js is a full application framework that decides where and when that UI gets rendered.
The Core Difference: Where Rendering Happens
This is the part that actually matters for a business decision, more than any feature list. With a plain React SPA, a search engine crawler or a visitor with a slow connection first receives a mostly blank HTML shell. Content only appears after JavaScript downloads and runs. With Next.js (SSR/SSG) or a prerendered React build, the crawler and the visitor receive fully-formed HTML immediately, with the JavaScript coming in afterward to make the page interactive.
SEO Implications
Google's crawler can execute JavaScript and index CSR pages, but it does so in a second rendering pass that can be delayed by days or weeks on lower-authority sites, and it is not guaranteed to complete for every page. Other crawlers matter too: Bing's JS rendering is weaker, and link-preview scrapers used by WhatsApp, Facebook, and LinkedIn for Open Graph cards generally do not execute JavaScript at all — which is a real problem for a business that shares links on social media and messaging apps, both dominant traffic sources in Indonesia. If organic search visibility or clean social link previews matter to your business, shipping pre-rendered or server-rendered HTML is not optional, it is the baseline requirement.
Performance and Core Web Vitals
SSR and SSG typically win on Largest Contentful Paint (LCP) because the browser has content to paint immediately instead of waiting for JS execution. A pure CSR app can still hit good Core Web Vitals scores, but it takes deliberate work: code splitting, lazy loading below-the-fold components, and keeping the initial JS bundle small. Next.js does a lot of this automatically through its build pipeline; a plain React SPA leaves it entirely up to the developer to get right, which is where a lot of unoptimized React sites end up with poor mobile performance.
Hosting and Cost for Indonesian SMEs
This is where the decision gets practical. A static React or prerendered site is just files — HTML, CSS, JS — that any nginx server, cPanel hosting, or a free-tier static host can serve. There is no Node.js process to keep alive, no server cost that scales with traffic, and no cold-start latency. A Next.js app using SSR needs a Node.js server running continuously (or serverless functions on a platform like Vercel), which means either paying for that hosting tier or accepting the platform's usage-based pricing once you outgrow the free tier — a real consideration for an SME still validating a business model. Vercel's free tier is generous for a small site, but heavier SSR traffic, image transformations, or ISR revalidation can push a growing business into paid plans faster than expected. If your Next.js app is 100% static-generated (SSG) at build time, this cost concern mostly disappears, since the output is again just static files.
Developer Experience and Speed to Ship
Next.js is genuinely faster to start a project with — routing, image handling, and API routes are built in, so there is less boilerplate decision-making early on. That convenience comes with more opinions about folder structure and rendering model, which can slow a team down once the project deviates from the framework's assumptions. Plain React with Vite has a smaller initial footprint and fewer opinions, but every piece — router, data fetching, SEO handling — is a separate decision the team has to make and maintain correctly.
The Middle Ground: Vite + React with Prerendering
There is a third option that gets skipped in most React vs Next.js comparisons: a Vite + React SPA with a build-time prerendering step (we use Puppeteer at KayFreyTech). The build runs a headless browser against every route, captures the fully-rendered HTML, and writes it to disk. The result is static HTML files identical in spirit to Next.js SSG — crawlers and social scrapers get real content immediately — but hosted as plain static files with none of the SSR server cost or complexity. This does not work for pages that need per-request personalization or real-time data (a logged-in dashboard, live pricing, cart state), because prerendering happens once at build time. But for marketing sites, landing pages, blogs, and most SME websites where content is the same for every visitor, it is a legitimate and often cheaper alternative to Next.js.
Decision Framework by Business Type
Our Recommendation
For most Indonesian SME business websites — company profiles, product catalogs, service pages, blogs — we default to React + Vite with Puppeteer prerendering. It gives full SEO visibility, consistently strong PageSpeed scores, and hosting costs that stay flat as traffic grows, which matters when a client's budget is fixed. We reach for Next.js when a project genuinely needs server-side logic per request: real-time inventory, user-specific pricing, or an app-like product where CSR interactivity matters more than static SEO. Neither framework is objectively better; the mistake is picking one without mapping it to what the business actually needs to render, and when. If you are not sure which category your project falls into, [talk to us](/get-quote/) and we'll walk through it with you before any code gets written.
Bottom Line
React answers "how do I build the interface." Next.js answers "where and when does that interface get rendered, and how do visitors and crawlers see it before JavaScript loads." A CSR-only React app is the wrong choice for anything that needs to rank in search or preview correctly on social media. Next.js solves that but adds server cost and framework opinions you may not need. Prerendered React with Vite is often the pragmatic middle path for SME sites that need SEO without the ongoing cost of a Node server.
