Next.js 15
New Era of React Performance

Next.js 15 is not just another version increment. It marks the stabilization of several paradigm-shifting technologies: the React Compiler, Partial Prerendering, and a complete overhaul of the caching strategy.
For years, developers have wrestled with the complexities of useEffect dependencies, memoization, and aggressive caching defaults. Next.js 15 aims to solve these DX (Developer Experience) friction points while unlocking performance gains that were previously impossible manually.
1. The React Compiler: No More useMemo
This is arguably the biggest change in the React ecosystem in a decade. The React team (and the Next.js team by extension) has introduced an optimizing compiler that automatically memoizes your components and hooks.
Before (The Manual Way)
We had to verify dependency arrays and wrap extensive calculations manually.
// ❌ The old, manual way
const expensiveValue = useMemo(() => {
return items.reduce((acc, item) => acc + item.value, 0);
}, [items]); // Don't forget dependencies!
const handleClick = useCallback(() => {
console.log(expensiveValue);
}, [expensiveValue]);After (Next.js 15 + React 19)
Just write JavaScript. The compiler handles the rest.
// ✅ Next.js 15 way
const expensiveValue = items.reduce((acc, item) => acc + item.value, 0);
const handleClick = () => {
console.log(expensiveValue);
};The compiler intelligently analyzes your code during the build process to determine what needs to be memoized, eliminating an entire class of performance bugs related to cascading re-renders.
2. Caching: Uncached by Default
In Next.js 13/14, the fetch API was cached by default. While performant, this confused many developers who expected their API calls to fetch fresh data.
Next.js 15 flips this heuristic. Fetch requests are now uncached by default (no-store). You must opt-in to caching. This aligns better with standard web standards and developer expectations.
The New Caching Strategy
- GET Route Handlers: Dynamic by default.
- Fetch: Uncached (
no-store) by default. - Client Router Cache: Now officially configurable via
staleTimes.
3. Partial Prerendering (PPR)
PPR is the "Holy Grail" of web rendering. It combines the ultra-fast initial load of Static Site Generation (SSG) with the dynamic capabilities of Server-Side Rendering (SSR).
Imagine a dashboard. The sidebar, logo, and navigation are static. The user profile and analytics chart are dynamic. With PPR, Next.js sends the static shell instantly (from the Edge) and then streams the dynamic parts as they finish computing.
import { Suspense } from 'react';
import { StaticSidebar } from './sidebar';
import { DynamicChart } from './chart';
export const experimental_ppr = true; // Enable PPR
export default function Dashboard() {
return (
<div className="flex">
<StaticSidebar /> {/* Sent instantly */}
<main>
<h1>Analytics</h1>
<Suspense fallback={<Skeleton />}>
<DynamicChart /> {/* Streamed in later */}
</Suspense>
</main>
</div>
);
}4. Async Request APIs
This is a breaking change to be aware of. APIs that rely on runtime information (like headers(), cookies(), params, and searchParams) are now asynchronous.
This change is necessary for standardizing how the server runtime handles request data, paving the way for further optimizations in the future.
// Old (Next.js 14)
// const params = useParams(); // sync
// New (Next.js 15)
const { slug } = await params; // asyncNext.js 15.1 & Turbopack: Now Stable
Since this article was published, Next.js 15.1 has shipped and Turbopack has reached its first stable release for next dev:
- 15.1Turbopack Dev is Stable — After years in beta, Turbopack is now the recommended dev server. It delivers up to 76% faster initial compilation and 96% faster HMR (hot module replacement) compared to webpack. Opt in by running
next dev --turbopack. - 15.1after() API is Stable — The
after()function (introduced as experimental in Next.js 15) lets you execute code after a response has been streamed to the user — perfect for logging, analytics, and cleanup tasks without blocking the response. - TIPPPR is still Incremental — Partial Prerendering remains opt-in per route. The Next.js team has confirmed it will become the default in a future major version. Early adoption now means easier migration later.
Conclusion
Next.js 15 represents a maturity milestone. It moves away from "magic" defaults (like auto-caching) towards explicit, predictable behavior, while simultaneously introducing profound automated optimizations like the React Compiler.
If you are still on Next.js 12 or 13, now is the time to upgrade. The stability and performance gains are finally substantial enough to justify the migration effort.