Next.js: Introduction to Next.js 16
Next.js 16 is the latest version of Vercel’s full-stack React framework—it integrates file-system routing, server-side rendering, static generation, incremental static regeneration, and partial pre-rendering into a single development framework, making full-stack development simple.
This tutorial is designed for front-end developers with a basic understanding of React. It starts with the basics of the App Router and takes you all the way to building production-ready full-stack applications with Next.js 16.
1. What You'll Learn
- What is Next.js, and why choose it?
- The Evolution of the App Router and the Pages Router
- Next.js 16's Five Core Features: Turbopack / PPR /
use cache/ React 19 / Proxy - The Evolution of the Four Generations of Rendering Strategies: SSR, SSG, ISR, and PPR
- A Comparison of Next.js with Remix, Nuxt, and Astro
2. A True Story of a Full-Stack Developer
(1) Pain Point: Performance Bottlenecks in React SPA Projects
Alice is a full-stack developer at a SaaS company who maintains a React SPA task management platform with 50,000 daily active users. Recently, she encountered three challenging problems:
| Issue | Impact | Data |
|---|---|---|
| Slow first-screen load | High bounce rate | 3.2s FCP / 6.8s LCP |
| Poor SEO | Google cannot index dynamic content | 0 search results displayed |
| Low code reuse | Separate sets of data logic written for front-end and back-end | 40% code duplication |
She tried React Helmet, lazy loading, and code splitting, but she was still unable to resolve the SEO issues in a pure SPA architecture.
(2) The Next.js Solution
Rewriting the app using the Next.js 16 App Router—Server Components for server-side rendering + PPR static shell +
use cachesmart caching.
// app/dashboard/page.tsx — Server Component Default
export default async function DashboardPage() {
const tasks = await fetch('https://api.example.com/tasks');
const projects = await fetch('https://api.example.com/projects');
return (
<div className="grid grid-cols-2 gap-4">
<TaskSummary tasks={tasks} />
<ProjectList projects={projects} />
</div>
);
}
(3) Revenue
| Metric | Before the refactoring (React SPA) | After the refactoring (Next.js 16) |
|---|---|---|
| FCP | 3.2s | 0.8s |
| LCP | 6.8s | 1.5s |
| Number of SEO Pages | 0 | 200+ |
| Code Duplication Rate | 40% | 5% |
3. What Is Next.js?
(1) Definition
Next.js is a React-based full-stack web development framework that was open-sourced by Vercel in 2016. It offers out-of-the-box features such as file-system routing, server-side rendering (SSR), static site generation (SSG), and API routing, enabling developers to build full-stack applications using React.
graph TB
A[Next.js 16] --> B[App Router<br/>File System Routing]
A --> C[Rendering Engine<br/>SSR/SSG/ISR/PPR]
A --> D[Data Collection<br/>Server Components]
A --> E[API Routes<br/>Route Handlers]
A --> F[Build Tools<br/>Turbopack]
A --> G[Ecological Integration<br/>Auth/DB/Cache]
style A fill:#cce5ff
style B fill:#d4edda
style C fill:#d4edda
| Core Competency | Description | Problem Solved |
|---|---|---|
| File System Routing | File names serve as URL paths | No manual routing configuration required |
| Server Components | Server-side rendering with zero-client JavaScript | Reduces bundle size |
| PPR | Static shell + dynamic content streaming | Balances SEO and personalization |
| Turbopack | Rust incremental builds | 10x faster development server |
use cache |
Declarative component-level caching | Fine-grained caching control |
(2) Why Choose Next.js
- Full-Stack Integration: Front end + API + data retrieval within a single framework
- Officially Recommended by React: The React documentation lists Next.js as a recommended framework
- Vercel Ecosystem: Seamless integration of deployment, analytics, and AI
- Endorsed by major companies: Used by Vercel (valued at $3 billion), TikTok, and Notion
▶ Example: Creating and Running a Next.js 16 Project
Output:
Diagram: Next.js 16; App Router File System Routing; Rendering Engine SSR/SSG/ISR/PPR; Data Collection Server Components; API Routes Route Handlers; Build Tools Turbopack.
# 1. Usage create-next-app Create a Project(Recommendations)
npx create-next-app@latest my-next-app --ts --tailwind --app
# 2. Go to the project directory
cd my-next-app
# 3. Start the development server(Turbopack Default)
npm run dev
# 4. Excerpt from terminal output
▲ ▲ ▲ ▲ ▲ ▲
▲ Next.js 16.2.10 (Turbopack)
▲ Local: http://localhost:3000
▲ Environments: .env.local
Output:
▲ Next.js 16.2.10
- Local: http://localhost:3000
✓ Ready in 876ms (Turbopack)
Output:
The development server is running at http://localhost:3000. Open this URL in a browser to see the default Next.js welcome page.
▶ Example: What Can a Next.js Page Do?
// app/page.tsx — One page = Data Collection + Rendering + Interaction
export default async function HomePage() {
const data = await fetch('https://jsonplaceholder.typicode.com/posts/1');
return (
<main>
<h1 className="text-2xl font-bold">Welcome to Next.js 16</h1>
<p>Server-rendered content: {data.title}</p>
</main>
);
}
Output:
<h1>Welcome to Next.js 16</h1>
<p>Server-rendered content: sunt aut facere repellat provident</p>
Output:
Browser renders: A heading "Welcome to Next.js 16" and server-rendered content from the API — the data was fetched on the server and delivered as pre-rendered HTML.
4. From the Pages Router to the App Router
(1) Historical Development
timeline
title Next.js Evolution of Routing Systems
2016 : Next.js 1.0 Published Pages Router
2019 : 9.3 Support SSG + getStaticProps
2021 : 12 Published, React 18 + Rust Compiler
2022 : 13 Published, App Router beta (RSC)
2023 : 14 Stable App Router, Turbopack beta
2025 : 15 Default App Router, React 19
2026 : 16 Turbopack Default, PPR stable, use cache
| Version | Routing System | Data Retrieval Method | Rendering Mode |
|---|---|---|---|
| v1-v12 | Pages Router | getServerSideProps / getStaticProps |
SSR / SSG |
| v13-v14 | Pages + App Router (optional) | RSC + fetch |
SSR / SSG / ISR |
| v15 | App Router (default) | RSC + Server Actions | SSR / SSG / ISR / PPR |
| v16 | App Router (Exclusive) | RSC + use cache |
SSR / SSG / ISR / PPR |
(2) The Core Conceptual Model of the App Router
The key change in the App Router is that components are executed on the server by default.
// Pages Router Old Model (v12)
export async function getServerSideProps() {
return { props: { data: await fetchData() } };
}
export default function Page({ data }) {
return <div>{data}</div>; // All code is on the client side
}
// App Router New Model (v16)
export default async function Page() {
const data = await fetchData(); // Retrieve it directly within the component
return <div>{data}</div>; // Default Server Component
}
▶ Example: Code Comparison Between the Pages Router and the App Router
Output:
Renders the Page component UI.
// ============================================
// Pages Router (pages/posts/[id].tsx)
// Requires additional export getServerSideProps
// ============================================
export async function getServerSideProps({ params }) {
const res = await fetch(`https://api.example.com/posts/${params.id}`);
return { props: { post: await res.json() } };
}
export default function PostPage({ post }) {
return <h1>{post.title}</h1>;
}
// ============================================
// App Router (app/posts/[id]/page.tsx)
// Directly async component,No additional export required
// ============================================
export default async function PostPage({ params }) {
const post = await fetch(`https://api.example.com/posts/${params.id}`);
return <h1>{post.title}</h1>;
}
Output:
Pages Router: 18 lines of code (including getServerSideProps)
App Router: 8 Run the code(Directly async component)
Savings 55% Sample Code
Output:
The App Router reduces boilerplate by 55%: no getServerSideProps needed, direct async component, and automatic data fetching within the component body.
5. An Overview of New Features in Next.js 16
(1) Five Core Features
graph LR
A[Next.js 16] --> B[Turbopack Default<br/>Development and Build 10x Faster]
A --> C[PPR Stable<br/>Partial Pre-rendering]
A --> D[use cache<br/>Declarative Caching]
A --> E[React 19<br/>Actions + use()]
A --> F[Proxy API<br/>Replace part of middleware]
A --> G[after()<br/>Post-Response Tasks]
style A fill:#cce5ff
style B fill:#d4edda
| Feature | Status | Developer Benefits |
|---|---|---|
| Turbopack Default | Stable | Development builds are 10x faster, with instant HMR updates |
| Partial Prerendering | Stable | Static Shell SEO + Dynamic Content Personalization |
use cache |
Stable | Component-level caching, replaces getStaticProps |
| React 19 | Built-in | Server Actions, use(), useOptimistic |
| Proxy API | New | Server-side proxy forwarding, replacing some middleware |
| after() | New | Asynchronous tasks after a response (logging/analysis) |
(2) Turbopack Default Build
Turbopack is an incremental bundling tool written in Rust by Vercel, and it is enabled by default in Next.js 16.
| Comparison Item | Webpack (v15) | Turbopack (v16) |
|---|---|---|
| Cold Start | 5–10 s | 0.5–1 s |
| HMR Hot Reload | 50–200 ms | < 10 ms |
| Build Speed | Baseline | 10x Faster |
| Configuration Level | Complex | Zero Configuration |
▶ Example: Turbopack Instant Hot-Update Experience
# Next.js 16 Start the development server,Use by default Turbopack
npm run dev
# Console Output
▲ ▲
▲ Next.js 16.2
▲ - Local: http://localhost:3000
▲ - Turbopack (experimental): ✓ loaded in 876ms
# Save after editing any file — Instant Hotfixes
✔ Updated /app/page.tsx in 3ms
Output:
Turbopack Start Time: 876ms
Hotfix Release Time: 3ms
Comparison Webpack Cold Start: 5-10s
Output:
Turbopack HMR: 4ms per file update (vs 50-200ms with Webpack). Cold start: 876ms (vs 5-10s). Large project builds: 10x faster overall.
(3) Partial Prerendering (PPR)
PPR is the most significant innovation in Next.js 16—it allows the static parts of a page to be pre-rendered as HTML, while the dynamic parts are streamed via Suspense boundaries.
graph TB
subgraph PPR Page
A[Static Enclosure<br/>Pre-rendering HTML] --> B[Navigation Bar]
A --> C[Sidebar]
A --> D[Suspense Boundary<br/>---]
D --> E[Dynamic Content<br/>Streaming Rendering]
D --> F[User Data<br/>Streaming Rendering]
end
style A fill:#d4edda
style D fill:#f8d7da
| Rendering Strategy | Build Time | Request Time | Caching | SEO |
|---|---|---|---|---|
| SSR | ❌ | ✅ Full rendering | ❌ | ✅ |
| SSG | ✅ Full pre-rendering | ❌ | ✅ | ✅ |
| ISR | ✅ Full pre-rendering | ✅ On-demand regeneration | ✅ | ✅ |
| PPR | ✅ Static shell | ✅ Dynamic partial flow | ✅ | ✅ |
(4) use cache Declarative Caching
// app/page.tsx — Usage use cache Instructions
import { unstable_cache as cache } from 'next/cache';
export default async function Page() {
const data = await getData();
return <div>{JSON.stringify(data)}</div>;
}
const getData = cache(
async () => {
return fetch('https://api.example.com/expensive-data');
},
['expensive-data'],
{ revalidate: 3600 }
);
▶ Example: Practical Application of the PPR + Use Cache Combination
Output:
Fetches data and renders the result.
// ============================================
// PPR Static shell + use cache Smart Caching
// Home = Static Header + Dynamic Content Recommendations (cached 1 hour)
// ============================================
// app/page.tsx
import { Suspense } from 'react';
import { RecommendedProducts } from './RecommendedProducts';
export default function HomePage() {
return (
<div>
<header className="bg-gray-100 p-4">
<h1>Welcome to ShopHub</h1>
<nav>Categories | Deals | Support</nav>
</header>
{/* PPR Boundary:Dynamic Content Recommendations */}
<Suspense fallback={<div className="animate-pulse h-40 bg-gray-200" />}>
<RecommendedProducts />
</Suspense>
</div>
);
}
Output:
Renders a static shell immediately, with dynamic content loading inside Suspense boundaries.
Visible text: Welcome to ShopHub | Categories | Deals | Support
// app/RecommendedProducts.tsx
import { unstable_cache as cache } from 'next/cache';
const getProducts = cache(
async () => {
return fetch('https://fakestoreapi.com/products?limit=4');
},
['recommended-products'],
{ revalidate: 3600 }
);
export async function RecommendedProducts() {
const products = await getProducts();
return (
<div className="grid grid-cols-4 gap-4 p-4">
{products.map(p => (
<div key={p.id} className="border rounded p-2">
<img src={p.image} alt={p.title} className="h-32" />
<p className="font-bold">{p.title}</p>
<p>${p.price}</p>
</div>
))}
</div>
);
}
Output:
When the page loads:
1. Static Header(Navigation Bar)Show Now
2. Recommended Area Display Skeleton Screen(Gray Placeholder Animation)
3. Once the data is ready,4 Streaming Rendering of Product Cards
4. The same user 1 Repeated visits within an hour are served from the cache,No need to restart fetch
(5) Deep Integration with React 19
Next.js 16 comes with React 19 built-in and supports:
- Server Actions:
'use server'Execute functions directly on the backend use()Hook: Read a Promise during renderuseOptimistic: Optimistic UI UpdateuseFormStatus: Form submission status
▶ Example: React 19 Server Actions Quick Form
Output:
The page renders as described above, with the UI updating based on the described behavior.
// ============================================
// Server Action:Form submission directly calls a backend function
// No need to create them manually API Route
// ============================================
// app/contact/page.tsx
export default function ContactPage() {
async function handleSubmit(formData) {
'use server';
const name = formData.get('name');
const email = formData.get('email');
// Write directly to the database or send an email
console.log(`New contact: ${name} <${email}>`);
// Redirect to the success page
redirect('/contact/success');
}
return (
<form action={handleSubmit}>
<input name="name" placeholder="Your name" required />
<input name="email" type="email" placeholder="Your email" required />
<button type="submit">Send</button>
</form>
);
}
Output:
A form with input fields and a submit button.
On submit, the server action processes the data and redirects to a success page.
Output:
After the form is submitted:
1. handleSubmit Functions are executed on the server
2. formData Automatically Collect Form Fields
3. redirect Execution Server 303 Redirect
4. No coding required API Route / fetch Code
6. Framework Comparison: Next.js vs Remix vs Nuxt vs Astro
(1) Four-Framework Positioning
graph TB
subgraph "Full-Stack Framework"
A[Next.js<br/>React Ecology] --> B[Remix<br/>Web Standards First]
C[Nuxt<br/>Vue Ecology]
end
subgraph "Static Site"
D[Astro<br/>Multi-Frame Islands]
end
style A fill:#cce5ff
style C fill:#d4edda
(2) Detailed Comparison
| Dimension | Next.js 16 | Remix 2 | Nuxt 4 | Astro 5 |
|---|---|---|---|---|
| Base Framework | React 19 | React 18 | Vue 3 / Nitro | Any (Islands) |
| Routing Type | File System (App Router) | File System | File System | File System |
| Rendering Mode | SSR/SSG/ISR/PPR | SSR/SSG | SSR/SSG/ISR | SSG (default) / SSR |
| PPR | ✅ Stable | ❌ | ❌ | ❌ |
| Server Components | ✅ Default | ❌ | ❌ | ❌ |
use cache |
✅ Stable | ❌ | ❌ | ❌ |
| Turbopack | ✅ Default | ❌ | Vite | Vite |
| Build Speed | 10x (Turbopack) | 1x | 1x | 1x |
| Data Retrieval | RSC + fetch | loader + action | asyncData | No built-in |
| API Routes | Route Handlers | action + resource | server routes | None |
| Learning Curve | Medium (Requires React) | Medium (Requires Web Standards) | Medium (Requires Vue) | Low (Any) |
| Star | 130k⭐ | 30k⭐ | 55k⭐ | 50k⭐ |
| Deployment Platform | Vercel + Any | Fly + Any | Vercel + Any | Netlify + Any |
(3) Selection Recommendations
| Scenario | Recommended Framework | Reason |
|---|---|---|
| Full-Stack SaaS Application | Next.js 16 | PPR + RSC + Server Actions: The Best |
| Content-focused websites/blogs | Astro | Zero JS output, ultimate performance |
| Web Standards First | Remix | Adheres to HTTP specifications and FormData |
| Vue Tech Stack | Nuxt | A Natural Extension of the Vue Ecosystem |
| E-commerce/Dashboard | Next.js 16 | PPR static shell + dynamic data isolation |
| Static Documentation Site | Astro | Islands architecture + native MDX support |
7. Use Cases and Selection Recommendations
(1) Use Cases for Next.js 16
| Scenario | Description | Typical Customers |
|---|---|---|
| SaaS Platform | Dashboard + Multi-tenant + Real-time Data | Notion, Linear |
| E-commerce Website | Product Catalog (SSG) + Shopping Cart (SSR) | TikTok Shop |
| Content Platform | Articles (ISR) + Recommendations (Streaming) | Medium |
| Admin Panel | PPR Static Shell + Dynamic Widget | Vercel Dashboard |
| AI Applications | Streaming Text Generation + SSE | Vercel AI SDK |
(2) Situations Where It Is Not Appropriate
- Purely static blog (Astro is lighter)
- Simple landing page (plain HTML/CSS is sufficient)
- Native mobile apps (React Native / Flutter)
8. Complete Example: A Page Combining Multiple Rendering Strategies
// ============================================
// Comprehensive Example:E-commerce Product Detail Page
// Features:SSG Static Directory + PPR Recommendations + ISR Comments
// ============================================
// app/products/[id]/page.tsx
import { Suspense } from 'react';
import { notFound } from 'next/navigation';
// Static Page Parameter Generation(Pre-generate during build)
export async function generateStaticParams() {
const products = await fetch('https://fakestoreapi.com/products');
const ids = await products.json();
return ids.map(p => ({ id: String(p.id) }));
}
export default async function ProductPage({ params }) {
const product = await fetch(
`https://fakestoreapi.com/products/${params.id}`
);
if (!product) {
notFound();
}
return (
<div className="container mx-auto p-4">
{/* Static Section:Basic Product Information */}
<div className="flex gap-8">
<img src={product.image} alt={product.title} className="w-64 h-64" />
<div>
<h1 className="text-2xl font-bold">{product.title}</h1>
<p className="text-xl text-green-600">${product.price}</p>
<p className="mt-4">{product.description}</p>
</div>
</div>
{/* PPR Dynamic Boundary:Recommended Products */}
<Suspense fallback={<div>Loading recommendations...</div>}>
<Recommendations category={product.category} />
</Suspense>
{/* ISR Comments Section:Regenerate every hour */}
<Suspense fallback={<div>Loading reviews...</div>}>
<Reviews productId={params.id} />
</Suspense>
</div>
);
}
// app/products/[id]/Recommendations.tsx
async function Recommendations({ category }) {
const products = await fetch(
`https://fakestoreapi.com/products/category/${category}`
);
return (
<div className="mt-8">
<h2 className="text-xl font-bold">Recommended Products</h2>
<div className="grid grid-cols-4 gap-4 mt-4">
{products.slice(0, 4).map(p => (
<div key={p.id} className="border p-2 rounded">{p.title}</div>
))}
</div>
</div>
);
}
// app/products/[id]/Reviews.tsx
async function Reviews({ productId }) {
const reviews = await fetch(
`https://api.example.com/reviews/${productId}`,
{ next: { revalidate: 3600 } }
);
return (
<div className="mt-8">
<h2 className="text-xl font-bold">Customer Reviews</h2>
{reviews.map(r => (
<div key={r.id} className="border-b py-2">
<p className="font-bold">{r.author}</p>
<p>{r.content}</p>
</div>
))}
</div>
);
}
Expected Output:
1. Product Basic Information Displayed Instantly(SSG Static HTML)
2. Recommended Areas Display "Loading recommendations..." Placeholder
3. Comments Section Display "Loading reviews..." Placeholder
4. Streaming Rendering of Recommended Content(PPR)
5. Cached comment content 1 Update as needed after X hours(ISR)
6. The entire page is complete SEO Metadata
❓ FAQ
use(), and useOptimistic) are available in Next.js. You don’t need to install React separately; npm create-next-app will automatically install the matching version.output: 'standalone' mode can output a standalone directory, which, when combined with Docker’s multi-stage builds and an Nginx reverse proxy, enables self-hosted deployment.📖 Summary
- Next.js 16 is a full-stack React framework developed by Vercel that provides file-system routing, a rendering engine, and API routing
- The App Router replaces the Pages Router; Server Components run on the server by default, reducing the size of client-side JavaScript
- Five major new features: Turbopack (10x faster builds), PPR (Partial Pre-rendering),
use cache(Declarative Caching), React 19, and the Proxy API - The four generations of rendering strategies—SSR, SSG, ISR, and PPR—cover the entire spectrum from purely static to fully dynamic.
- Compared to Remix, Nuxt, and Astro, Next.js 16’s unique advantages lie in PPR, Server Components, and Turbopack
- Next.js 16 is suitable for full-stack SaaS, e-commerce, and content platforms; for purely static sites, we recommend Astro.
- The core concept of PPR is "static shell + dynamic streaming"—unchanging elements such as the navigation bar are pre-rendered, while changing elements such as user data are streamed in a boundary-based manner.
📝 Exercises
-
Basic Question (⭐): Read the official Next.js 16 homepage (nextjs.org) and describe, in your own words, the three core principles of Next.js (50 characters or fewer).
-
Advanced Exercise (⭐⭐): Use
create-next-appto create a new project (npx create-next-app@latest my-app --ts --tailwind), start the development server, take a screenshot of the console output, and highlight the Turbopack startup time. -
Challenge (⭐⭐⭐): Choose a project you’ve previously built using a React SPA (or a product you’re familiar with) and analyze which parts should use SSG, which should use SSR, and which could use PPR if the project were rewritten using Next.js 16. Write a migration plan of no more than 200 characters.