Next.js 15 brings groundbreaking improvements to React development with enhanced performance, better developer experience, and cutting-edge features that make building modern web applications faster and more efficient than ever.
Next.js 15 is built on React 19, bringing you the latest React features including:
BASH1# Development with Turbopack (up to 53% faster) 2npm run dev --turbo
Benefits:
JAVASCRIPT1// Before Next.js 15 2export async function generateMetadata({ params }) { 3 const id = params.id; // Synchronous access 4} 5 6// Next.js 15 - Async support 7export async function generateMetadata({ params }) { 8 const { id } = await params; // Now async! 9 const post = await fetch(`/api/posts/${id}`); 10 return { title: post.title }; 11}
JAVASCRIPT1// Granular cache control 2export const revalidate = 3600; // Revalidate every hour 3export const dynamic = 'force-static'; // Force static generation 4export const fetchCache = 'default-cache'; // Control fetch caching
| Feature | Improvement | Impact | |---------|-------------|---------| | Dev Server | 53% faster startup | ā” Instant development | | Hot Reload | 94% faster updates | š Real-time changes | | Build Process | 76% faster builds | š Faster deployments | | Bundle Size | 20% smaller bundles | š¦ Better performance |
JAVASCRIPT1// Improved dynamic imports 2const DynamicComponent = dynamic(() => import('./heavy-component'), { 3 loading: () => <Skeleton />, 4 ssr: false, // Enhanced SSR control 5});
BASH1# Create a new Next.js 15 project 2npx create-next-app@latest my-next15-app 3 4# Or upgrade existing project 5npm install next@latest react@latest react-dom@latest
my-next15-app/
āāā app/ # App Router (recommended)
ā āāā layout.tsx # Root layout
ā āāā page.tsx # Home page
ā āāā globals.css # Global styles
ā āāā api/ # API routes
āāā components/ # Reusable components
āāā lib/ # Utility functions
āāā public/ # Static assets
āāā next.config.js # Next.js configuration
JAVASCRIPT1// next.config.js 2/** @type {import('next').NextConfig} */ 3const nextConfig = { 4 experimental: { 5 // Enable Turbopack for development 6 turbo: { 7 rules: { 8 '*.svg': { 9 loaders: ['@svgr/webpack'], 10 as: '*.js', 11 }, 12 }, 13 }, 14 // Server Actions improvements 15 serverActions: { 16 allowedOrigins: ['localhost:3000'], 17 }, 18 }, 19 // Enhanced image optimization 20 images: { 21 formats: ['image/avif', 'image/webp'], 22 deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840], 23 }, 24}; 25 26module.exports = nextConfig;
BASH1npm install next@15 react@19 react-dom@19 @types/react@19
JAVASCRIPT1// ā Old way (Next.js 14) 2export function generateStaticParams({ params }) { 3 return params.slug; 4} 5 6// ā New way (Next.js 15) 7export async function generateStaticParams({ params }) { 8 const { slug } = await params; 9 return { slug }; 10}
JAVASCRIPT1// Enhanced Server Actions with better error handling 2'use server'; 3 4export async function createPost(formData) { 5 try { 6 const title = formData.get('title'); 7 const content = formData.get('content'); 8 9 // Enhanced validation and error handling 10 if (!title || !content) { 11 return { error: 'Title and content are required' }; 12 } 13 14 // Your logic here 15 return { success: true }; 16 } catch (error) { 17 return { error: 'Failed to create post' }; 18 } 19}
JAVASCRIPT1// app/posts/page.tsx - Server Component (default) 2export default async function PostsPage() { 3 const posts = await fetchPosts(); // Runs on server 4 5 return ( 6 <div> 7 {posts.map(post => ( 8 <PostCard key={post.id} post={post} /> 9 ))} 10 </div> 11 ); 12}
JAVASCRIPT1'use client'; // Only when you need interactivity 2 3import { useState } from 'react'; 4 5export default function InteractivePost({ post }) { 6 const [liked, setLiked] = useState(false); 7 8 return ( 9 <div> 10 <h2>{post.title}</h2> 11 <button onClick={() => setLiked(!liked)}> 12 {liked ? 'ā¤ļø' : 'š¤'} Like 13 </button> 14 </div> 15 ); 16}
JAVASCRIPT1import Image from 'next/image'; 2 3export default function OptimizedImage() { 4 return ( 5 <Image 6 src="/hero-image.jpg" 7 alt="Hero" 8 width={1200} 9 height={600} 10 priority // Load above the fold images first 11 placeholder="blur" // Built-in blur placeholder 12 sizes="(max-width: 768px) 100vw, 50vw" 13 /> 14 ); 15}
TYPESCRIPT1// types/post.ts 2export interface Post { 3 id: string; 4 title: string; 5 content: string; 6 author: { 7 name: string; 8 email: string; 9 }; 10 createdAt: Date; 11 tags: string[]; 12} 13 14// app/posts/[id]/page.tsx 15import { Post } from '@/types/post'; 16 17interface PageProps { 18 params: Promise