Next.js, explained: the React framework behind the modern web

The short answer
Next.js is a React framework - the layer that turns React from a UI library into a complete way to build and ship websites and web applications. It adds the things React deliberately leaves out: routing, server rendering, static generation, data fetching, caching, image optimization, and a build system. If React is the engine, Next.js is the car.
It is open source, MIT-licensed, and stewarded by Vercel, the deployment company whose founder created it. It is also, at the time of writing, the most widely used way to build a serious React site - and it is what this very site is built on.
Why React needed a framework
React was released by Facebook in 2013 as a library for building interfaces. Deliberately, it did only one thing: render components and keep them in sync with your data. Everything else - how pages link together, how data reaches the page, whether the page is built on a server or in the browser - was your problem.
That freedom worked for Facebook but produced chaos everywhere else. A typical React project in 2015 meant assembling webpack configs, routing libraries, and rendering strategy by hand - days of setup before a single page could load, and the default result was a blank screen that JavaScript had to fill in. That default was quietly terrible for the web: search engines saw empty pages, and users on slow connections watched spinners.
Next.js existed to fix that. Give it pages in a folder and it handles routing, server-renders the first load so it arrives as real HTML, and manages the build. The pitch in 2016 was almost cheeky: a React site with zero configuration that behaves like a real website.
The origin story
Guillermo Rauch - an Argentine developer who had already built socket.io and Mongoose - founded a deployment startup called ZEIT and released Next.js on October 25, 2016. The two products were designed to fit together: a framework that made the right thing easy, and a host where `now` deployed it in seconds.
The framework spread fast because it solved a real pain at the right moment. React was exploding, single-page apps were hitting SEO and performance walls, and Next.js offered the escape hatch. Version 9 in 2019 added API routes and automatic static optimization, turning it from a site framework into a full-stack one. ZEIT renamed itself Vercel in 2020, and the pair - framework and platform - became the default stack for a generation of React work.
How a Next.js site actually works
The core idea is file-based routing: every file in the `app` directory becomes a URL. Write `app/about/page.tsx` and `/about` exists, with nested layouts, loading states, and error boundaries all derived from file names. There is no routing table to configure - the filesystem is the config.
Underneath that is where Next.js earns its name: the framework decides, per page and even per component, how a page gets rendered. A marketing page can be pre-built as static HTML and served from a CDN in milliseconds; a dashboard can render fresh on every request; a product page can be generated once and revalidated on a schedule. One project can mix all three.
The five rendering strategies
The most important concept in Next.js is that rendering is a per-page decision, not a per-app one. The options, in order of how often you will use them:
- Static generation (SSG) - the page is built once at deploy time and served from the edge; the default for marketing pages, blogs, and anything that does not change per visitor, and the fastest possible response
- Incremental Static Regeneration (ISR) - a static page that quietly rebuilds in the background on a schedule or on demand; how a site can have thousands of fast pages that still stay current
- Server-side rendering (SSR) - the page renders fresh per request on the server; for dashboards, personalized content, and anything that must reflect live data
- Client rendering - the classic React model, for genuinely interactive pieces; used inside components, not usually for whole pages
- Streaming and partial pre-rendering - the newest model, where the static shell arrives instantly and dynamic parts stream in behind it; the theory is that fast and fresh stop being a tradeoff
The App Router rewrite
The biggest event in Next.js history was version 13 in October 2022, which introduced the App Router - a ground-up redesign around React Server Components. Components became server-first by default: they render on the server, can read databases directly, and ship zero JavaScript to the browser unless they need interactivity.
The change was genuinely better and genuinely painful. The old Pages Router model was simpler; the new model was more powerful but asked developers to rethink where code ran, and the early version shipped with an implicit caching system that confused everyone - data that stayed stale for reasons invisible in the code. Version 13.4 stabilized App Router in May 2023, but the migration cost and the caching confusion became the two most-criticized chapters in the framework's history.
A brief version history
The framework's arc is easiest to see as a timeline, because each major release added one structural idea:
- 2016 - the open-source release: zero-config React with server rendering and file routing
- 2019 - version 9: API routes and automatic static optimization turn it full-stack
- 2020 - version 10: `next/image` and Incremental Static Regeneration make performance automatic
- 2021 - version 12: the Rust-based compiler era begins, middleware arrives
- 2022 - version 13: App Router in beta; the Server Components rewrite starts
- 2023 - version 13.4 stabilizes App Router; version 14 lands Server Actions
- 2024 - version 15: React 19 support, async request APIs, and saner caching defaults
- 2025 - version 16: Turbopack stable and default, Cache Components make caching explicit, `proxy.ts` replaces middleware
Server Components and Server Actions
React Server Components are the architectural heart of modern Next.js. A Server Component executes only on the server - it can query a database, read files, or call internal APIs - and sends down its rendered result, not its code. Interactive islands opt in with a `'use client'` directive. The effect on bundle size is real: the marketing page ships almost no JavaScript.
Server Actions close the loop in the other direction: a form or button calls a function that runs on the server - a mutation, a database write, an email - without you writing an API endpoint. Together they collapse the old split between "frontend" and "backend" code into one tree where the boundary is a directive, which is the largest mental-model change since React itself.
Data fetching, the modern way
In the App Router model, data fetching happens inside Server Components - a component is an `async` function that awaits its data directly, whether that is a database query, an ORM call through Prisma or Drizzle, or a fetch to an API. There is no `useEffect` round-trip: the server renders the data in, and the client receives the result.
React's `cache()` function deduplicates a fetch across a render, the `fetch` API accepts revalidation options, and Suspense boundaries let a slow component stream in while the rest of the page arrives instantly. The pattern replaces an entire generation of client-side data-fetching libraries for the common case - though those libraries still earn their place for highly interactive, client-heavy surfaces.
Next.js 16: where it stands now
The current major release, Next.js 16, is the most significant architectural update since the App Router. The headline changes:
- Turbopack is stable and default - the Rust-based bundler that replaced webpack delivers 2-5x faster production builds and up to 10x faster Fast Refresh in development
- Cache Components - the implicit caching that confused everyone is gone, replaced by an explicit opt-in `use cache` directive with Partial Pre-Rendering built in; the static shell is instant and dynamic parts stream in by default
- React Compiler support is stable - automatic memoization, ending years of manual `useMemo` and `useCallback` discipline
- `proxy.ts` replaces middleware.ts - the network boundary file renamed to say what it actually does
- React 19.2 - View Transitions and the newest React primitives are first-class
- A DevTools MCP server - Next.js itself now exposes debugging over the Model Context Protocol, so AI tools can inspect a running app during development
The built-in performance toolkit
Much of the framework's popularity comes from making the right performance choice the default. The `next/image` component lazy-loads, resizes, and serves modern formats automatically. Font loading is optimized to avoid layout shift. Links prefetch their targets in the viewport so navigation feels instant. Scripts and streaming are handled with sensible defaults.
None of it is magic - it is the boring correctness work every site should do and few actually did before a framework made it free. The measurable result is what the discipline in our PageSpeed Insights guide calls real-user metrics: pages built this way tend to pass Core Web Vitals without heroics.
The ecosystem around it
A framework this dominant grew an industry around itself. `create-next-app` scaffolds a project in seconds, and the default starter already assumes the modern stack: TypeScript, Tailwind for styling, and shadcn/ui - the component library pattern that pairs so naturally with React Server Components that it has become the de facto default UI kit for new Next.js projects.
Auth has its own gravity well too - Auth.js grew out of the NextAuth project specifically for this ecosystem - alongside the ORMs, headless CMS integrations, analytics snippets, and the marketplace of Vercel integrations. The practical effect is that a Next.js app rarely starts from zero: the framework is the trunk, and a mature ecosystem of assumed tools hangs off it.
The SEO surface
For a marketing site, Next.js's SEO features are table stakes done right: server-rendered HTML so search engines see real content, a metadata API that generates titles, descriptions, and Open Graph tags from code, and file conventions for `sitemap.xml`, `robots.txt`, and structured data. Everything the SEO article describes as technical groundwork is a few lines of framework code here.
The full-stack pieces
Next.js is not only frontend. Route Handlers let any file expose an API endpoint. `proxy.ts` sits at the network boundary for redirects, rewrites, and auth gates. OpenTelemetry instrumentation is built in. Paired with a backend like Supabase for the database and Stripe for payments - both wired through webhooks - a single Next.js app covers what used to take a frontend plus a separate API tier.
Who actually uses it
The showcase list is long enough to be unremarkable: parts of Nike, Uber, PayPal, The Washington Post, Sonos, TikTok's web surfaces, and countless startups. More telling is the quiet majority - the marketing sites, SaaS dashboards, docs platforms, and storefronts where Next.js is simply what gets reached for when the requirements are "fast, indexable, and able to grow into an app."
That reach is also the honest criticism of it: for a purely static blog with no interactivity, lighter tools like Astro can ship less JavaScript. Next.js is the right default when there is any real app surface; it is overkill when there truly is none.
The learning curve, honestly
For all its polish, Next.js asks more of a developer than it used to. The App Router's mental model - server-first components, `'use client'` boundaries, cache semantics, the difference between a page that renders once and one that renders per request - is genuinely powerful and genuinely more to learn. Beginners routinely hit the same walls: putting browser code in a Server Component, being surprised by cached data, or misunderstanding where a piece of code actually runs.
That is worth saying plainly because it is the framework's real cost. The trade for its capability is conceptual overhead - a full understanding requires holding both the server and client models at once. Teams that invest in the model get a lot back; a quick side project can be simpler in something smaller.
Vercel, Next.js, and the coupling question
Next.js is open source and works anywhere Node runs - `next build` produces a standalone output you can Docker and host on your own infrastructure. But it is stewarded by Vercel, and the framework's newest features land on Vercel's platform first and cleanest. That is a real strategic consideration, not a conspiracy: the two are designed together, the way a language and its best runtime are.
The honest take is that the coupling is real but shallow. Every page of this site is a Next.js app that could be hosted on a VPS tomorrow; the operational conveniences are what Vercel sells, not the lock-in. More on that tradeoff in the Vercel article.
Deploying it without Vercel
For teams avoiding the platform entirely, the paths are real: the standalone output runs under Node on any host or in a container; OpenNext produces builds shaped for Cloudflare, AWS Lambda, and similar targets; and hosts like Netlify and AWS Amplify support Next.js directly. The experience is less seamless - some features need configuration the platform would do for you - but nothing structural blocks it.
The alternatives worth knowing
The React space now has real competition. Astro leads for content-heavy sites that want islands of interactivity instead of a client app. SvelteKit offers a smaller, arguably more elegant model in the Svelte ecosystem. Remix's approach merged back into React Router 7. Nuxt does the equivalent job for Vue, and the AI era produced a new wave of generators - vibe coding tools - that scaffold Next.js apps by default precisely because its patterns are so heavily represented in training data.
Next.js and the AI toolchain
The framework's dominance shows up in a newer place: the AI toolchain. When a prompt-to-app builder or a coding agent scaffolds a project, Next.js is the default more often than not - because its conventions are so heavily represented in public code that the models produce it most reliably. Vercel's own v0 generates Next.js and shadcn/ui specifically, and the AI SDK made it the reference TypeScript environment for model-backed apps.
The result is a reinforcing loop: more training data in the framework's patterns means better AI output in it, which drives more projects to it, which creates more data. For the vibe-coded and AI-assisted era, Next.js is effectively the lingua franca.
Why we build on it
This site is a Next.js application: every page statically generated, every image through the optimizer, sitemap and metadata from the framework's own APIs, preview URLs on every change. The reasons it is our default are the boring good ones - it is fast by construction, indexable by construction, maintained by a team whose incentives run through the framework, and has the largest hiring and knowledge pool in its category.
More importantly, the architecture does not trap the result. If we hand the codebase to a client tomorrow, it is a standard open-source React project that runs anywhere - which matters more than any feature. If you are evaluating stacks or want to see it in practice, that is the conversation we have on the website development page and on a call.