HomeAboutContact
Dev
9 min read
DevApr 18, 20259 min read

Next.js 15 what every developer needs to know

Next.js 15 ships with Turbopack stable, the new React Compiler, improved caching defaults, and Partial Pre-rendering. Here's a deep dive into every change that matters.

SK
Joshua
Senior Full-Stack Dev · 4UR Tech

The release that changes how we think about performance

Next.js 15 is not just an incremental update. It represents a genuine rethinking of how the framework handles rendering, caching, and compilation and it ships with Turbopack as the stable, default bundler for the first time. If you're running a production Next.js app or starting a new project, this release deserves your full attention.

Let's break down every significant change, what it means for your day-to-day workflow, and how to migrate safely.

Upgrade note: Next.js 15 requires Node.js 18.17+ and React 19 RC or stable. Run npx @next/codemod@canary upgrade latest to apply automated migration codemods.

Turbopack is now stable

Turbopack Vercel's Rust-based bundler exits beta and becomes the default fornext dev in Next.js 15. The performance gains are substantial:

  • Up to 76% faster initial local server startup
  • Up to 96% faster code updates with Fast Refresh
  • Full support for all Next.js features including App Router, Server Components, and edge runtimes
  • Significantly reduced memory usage on large monorepos

You can opt out by passing --no-turbopack to the dev command if you encounter edge cases, but in our testing across a dozen production codebases the compatibility is now excellent.

# Start dev with Turbopack (default in Next.js 15)
next dev

# Opt out if needed
next dev --no-turbopack

The React Compiler

Next.js 15 ships experimental support for the React Compiler the Babel plugin that automatically memoises your components and hooks without manual useMemo,useCallback, or React.memo.

Enable it in your config:

// next.config.ts
import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  experimental: {
    reactCompiler: true,
  },
};

export default nextConfig;

In practice this means you can remove a significant portion of manual optimisation code. The compiler handles dependency tracking automatically, and in our benchmarks it reduced unnecessary re-renders by 30–50% in complex component trees without a single line of manual optimisation.

“The React Compiler is the single most impactful developer experience improvement in the React ecosystem in years. It turns performance best practices into the default.”

Caching semantics a breaking change worth knowing

This is where the most significant migration work lies. Next.js 15 changes the default caching behaviour for fetch requests, Route Handlers, and Client Router Cache.

fetch() is no longer cached by default

In Next.js 14, fetch() calls in Server Components were cached by default (equivalent to force-cache). In Next.js 15, the default isno-store meaning requests are not cached unless you opt in explicitly.

// Next.js 14 cached by default
const res = await fetch('https://api.example.com/data');

// Next.js 15 must opt into caching explicitly
const res = await fetch('https://api.example.com/data', {
  cache: 'force-cache',           // static / ISR
  // or
  next: { revalidate: 60 },       // revalidate every 60s
});

Route Handlers are no longer cached by default

GET Route Handlers that use the Request object are now dynamic by default. If you want static caching behaviour, explicitly return withexport const dynamic = 'force-static'.

Client Router Cache staleness reduced

Page segments in the Client Router Cache are no longer reused across navigations by default. This makes navigations feel more up-to-date at a small performance trade-off. You can restore the old behaviour with staleTimes in your config.

Partial Pre-rendering (PPR)

PPR is the feature that has the most long-term architectural significance. It allows a single route to be partially statically rendered serving a static shell instantly from the edge while dynamic, personalised content streams in via Suspense boundaries.

// app/dashboard/page.tsx
import { Suspense } from 'react';
import StaticHeader from './StaticHeader';   // rendered at build time
import DynamicFeed  from './DynamicFeed';    // streamed at request time

export default function DashboardPage() {
  return (
    <>
      <StaticHeader />
      <Suspense fallback={<FeedSkeleton />}>
        <DynamicFeed />
      </Suspense>
    </>
  );
}

// next.config.ts enable PPR
const nextConfig = {
  experimental: { ppr: 'incremental' },
};

Enable it incrementally per-route with export const experimental_ppr = true— you don't need to migrate your entire app at once.

Other notable changes

  • next/after schedule work after a response has finished streaming, without blocking the user
  • instrumentation.js is now stable hook into server lifecycle events for observability
  • Enhanced next/form component client-side navigation on form submit with prefetching
  • TypeScript config support next.config.ts is now officially supported
  • Improved create-next-app prompts and Turbopack as default for new projects

Should you upgrade now?

For new projects: absolutely yes. Start with Next.js 15 and Turbopack from day one.

For existing projects: run the codemod, audit your fetch calls for caching assumptions, test your Route Handlers, and upgrade in a staging environment first. The caching changes catch most teams off guard, but once you understand the new mental model opt-in caching rather than opt-out the behaviour is strictly more predictable.

Next.js 15 is the framework's most production-ready release yet. The combination of a stable Turbopack, the React Compiler, and Partial Pre-rendering puts it in a strong position heading into the second half of 2025.

Found this helpful?

Share it with your network