What's New in Next.js 15?


Next.js 15 shipped a lot of headlines: Partial Prerendering, caching changes, async request APIs. I cared less about the keynote slides and more about one question: what breaks in my existing App Router projects, and what gets easier?
This post is my honest field notes — not a full changelog. If you are still fuzzy on Server vs Client Components, read use client vs use server first. That mental model makes 15's changes click.
What changed: Fetch caching defaults and cache semantics shifted. Things I assumed were cached sometimes were not — and vice versa.
Why it matters: "It worked in dev" stopped being a reliable signal. I had to read cache behavior per route again instead of trusting muscle memory from Next 13.
What I do now:
cache: 'force-cache', no-store, or revalidate when I care about freshnessunstable_cache (or the stable equivalent in your version) for expensive reads I want to dedupe// app/blog/[slug]/page.tsx
import { unstable_cache } from "next/cache";
async function getPost(slug) {
const res = await fetch(`https://api.example.com/posts/${slug}`);
return res.json();
}
export default async function BlogPost({ params }) {
const post = await unstable_cache(getPost, ["post", params.slug])(params.slug);
return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}
Red flag: Sprinkling no-store everywhere because caching is confusing. You will pay in latency and cost. Decide per page what "fresh enough" means.
What: Ship a static shell fast, stream the dynamic parts.
Why I like it: Marketing pages with one personalized widget. Docs with a logged-in banner. The static part hits CDN; the dynamic part does not block first paint as hard.
What I do not use it for (yet): Fully dynamic dashboards where every pixel depends on live data. PPR helps hybrid pages most.
Red flag: Treating PPR as "free performance" without measuring. Profile LCP before and after.
Route params and search params became async in the App Router world. That sounds small. It broke a surprising amount of copy-pasted code.
What I learned: params and searchParams are Promises in server components now. await them before use.
Why: Clearer streaming and layout composition on the server. The migration pain is front-loaded.
Upgrade when you have time to read the migration guide — not Friday afternoon before a release.
My upgrade checklist:
params. and searchParams. in server components — add await where needed.fetch and document its cache intent.'use client' trees.Next.js 15 is not a new framework. It is a stricter teacher about caching and server boundaries. That is annoying for a week and useful for the next year.