Getting Started with Next.js 16: The Future of React Frameworks

5 min read

Why Next.js?

Next.js has long been the gold standard for production React applications, combining powerful server-side capabilities with an excellent developer experience. Next.js 16 takes this further with improved performance, enhanced Server Components support, and a refined App Router — making it the most compelling version yet. Next.js solves the fundamental problems of building production React apps out of the box:

ProblemNext.js Solution
Slow initial page loadServer-Side Rendering (SSR) + Streaming
SEO with ReactHTML rendered before JS loads
Routing boilerplateFile-system based routing
Image optimisationBuilt-in <Image> component
API endpointsRoute Handlers co-located with pages
PerformanceAutomatic code splitting + React Server Components

What's New in Next.js 16

Faster Compiler and Builds

Next.js 16 ships with a Rust-based compiler (Turbopack) enabled by default in development. This delivers:

  • ~76% faster local server startup
  • ~96% faster Fast Refresh (code changes reflect near-instantly)

Enhanced Server Components

React Server Components (RSC) let you fetch data and render HTML entirely on the server — sending zero JavaScript to the client for those components:

javascript
1// app/users/page.tsx — This runs on the server, never ships to the browser
2export default async function UsersPage() {
3 // Direct database/API call — no API route needed
4 const users = await db.user.findMany({ orderBy: { createdAt: 'desc' } });
5
6 return (
7 <main>
8 <h1>Users</h1>
9 {users.map(user => (
10 <div key={user.id}>
11 <p>{user.name}</p>
12 <p>{user.email}</p>
13 </div>
14 ))}
15 </main>
16 );
17}
UTF-8 17 Lines

Improved Caching Model

Next.js 16 gives developers explicit control over caching:

javascript
1// Cache this fetch indefinitely (static, like getStaticProps)
2const data = await fetch('/api/config', { cache: 'force-cache' });
3
4// Never cache — always fetch fresh (like getServerSideProps)
5const user = await fetch(`/api/users/${id}`, { cache: 'no-store' });
6
7// Revalidate every 60 seconds (like ISR)
8const posts = await fetch('/api/posts', { next: { revalidate: 60 } });
UTF-8 8 Lines

Getting Started

Create a New Project

bash
1npx create-next-app@latest my-app
2cd my-app
3npm run dev
UTF-8 3 Lines

The setup wizard prompts you for TypeScript, Tailwind CSS, ESLint, and the App Router — all recommended for new projects.

Project Structure (App Router)

javascript
1my-app/
2├── app/
3│ ├── layout.tsx # Root layout (wraps all pages)
4│ ├── page.tsx # Home page (/)
5│ ├── globals.css
6│ ├── about/
7│ │ └── page.tsx # /about route
8│ └── blog/
9│ ├── page.tsx # /blog route
10│ └── [slug]/
11│ └── page.tsx # /blog/:slug route
12├── components/
13├── lib/
14└── public/
UTF-8 14 Lines

Core Concepts

Layouts

Layouts wrap pages and persist across navigation without remounting:

javascript
1// app/layout.tsx
2export default function RootLayout({ children }) {
3 return (
4 <html lang="en">
5 <body>
6 <nav>
7 <a href="/">Home</a>
8 <a href="/blog">Blog</a>
9 </nav>
10 <main>{children}</main>
11 <footer>© 2026 My App</footer>
12 </body>
13 </html>
14 );
15}
UTF-8 15 Lines

Dynamic Routes

javascript
1// app/blog/[slug]/page.tsx
2interface Props {
3 params: { slug: string };
4}
5
6// Tell Next.js which slugs to pre-render at build time
7export async function generateStaticParams() {
8 const posts = await getPosts();
9 return posts.map(post => ({ slug: post.slug }));
10}
11
12export default async function BlogPost({ params }: Props) {
13 const post = await getPostBySlug(params.slug);
14
15 if (!post) notFound(); // Renders the nearest not-found.tsx
16
17 return (
18 <article>
19 <h1>{post.title}</h1>
20 <p>{post.publishedAt}</p>
21 <div dangerouslySetInnerHTML={{ __html: post.contentHtml }} />
22 </article>
23 );
24}
UTF-8 24 Lines

Route Handlers (API Endpoints)

javascript
1// app/api/users/route.ts
2import { NextRequest, NextResponse } from 'next/server';
3
4export async function GET(request: NextRequest) {
5 const { searchParams } = new URL(request.url);
6 const page = Number(searchParams.get('page') ?? '1');
7
8 const users = await db.user.findMany({
9 skip: (page - 1) * 20,
10 take: 20,
11 });
12
13 return NextResponse.json({ users, page });
14}
15
16export async function POST(request: NextRequest) {
17 const body = await request.json();
18 const user = await db.user.create({ data: body });
19 return NextResponse.json(user, { status: 201 });
20}
UTF-8 20 Lines

Client vs Server Components

javascript
1// ✅ Server Component (default) — no 'use client' directive
2// Can: async/await, access DB, read env secrets
3// Cannot: useState, useEffect, event handlers, browser APIs
4export default async function ProductList() {
5 const products = await getProducts(); // Direct DB call
6 return <ul>{products.map(p => <li key={p.id}>{p.name}</li>)}</ul>;
7}
8
9// ✅ Client Component — add 'use client' at the top
10// Can: useState, useEffect, onClick, access window/document
11// Cannot: async at component level, access secrets
12'use client';
13import { useState } from 'react';
14
15export function AddToCartButton({ productId }) {
16 const [added, setAdded] = useState(false);
17
18 return (
19 <button onClick={() => setAdded(true)}>
20 {added ? '✓ Added' : 'Add to Cart'}
21 </button>
22 );
23}
UTF-8 23 Lines

Metadata and SEO

javascript
1// app/blog/[slug]/page.tsx
2import type { Metadata } from 'next';
3
4export async function generateMetadata({ params }): Promise<Metadata> {
5 const post = await getPostBySlug(params.slug);
6
7 return {
8 title: post.title,
9 description: post.excerpt,
10 openGraph: {
11 title: post.title,
12 description: post.excerpt,
13 images: [{ url: post.coverImage }],
14 },
15 };
16}
UTF-8 16 Lines

Deployment

Next.js deploys effortlessly on Vercel (zero config), but also supports:

  • Dockernext build then next start in a Node container
  • AWS / GCP / Azure — via adapters or standard Node.js hosting
  • Static exportnext build && next export for pure static sites
bash
1# Build for production
2npm run build
3
4# Start production server
5npm start
UTF-8 5 Lines

Quick-Start Checklist

  • ✅ Use the App Router (not Pages Router) for all new projects
  • ✅ Default to Server Components — only add 'use client' when needed
  • ✅ Use next/image for all images
  • ✅ Use next/link for all internal navigation
  • ✅ Generate metadata with generateMetadata for SEO
  • ✅ Use Route Handlers for API endpoints
  • ✅ Enable TypeScript from the start
  • ✅ Measure performance with Lighthouse and Next.js Analytics

Summary

Next.js 16 is a mature, full-featured framework that handles the hard parts of production web development — routing, rendering strategy, caching, image optimisation, and TypeScript — so you can focus on building your product. Whether you're building a marketing site, a dashboard, or a full-stack SaaS application, Next.js provides the primitives to do it well.