Cache Components is the unified caching feature introduced in Next.js 16. You enable it with a single flag, cacheComponents: true, and from then on data fetching is dynamic by default while you choose what to cache. It replaces the older experimental PPR and caching flags.
Enable it in your config file:
// next.config.ts
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
cacheComponents: true,
}
export default nextConfigThat is the whole setup. Next.js reads the flag at build time and changes how pages, functions, and route handlers are rendered.
What the flag turns on
Turning the flag on gives you three new tools and two behavior changes.
- The
use cachedirective marks functions and components as cacheable. cacheLifesets a cache lifetime, andcacheTagtags entries for on-demand invalidation.- Partial Prerendering becomes the default, so the removed experimental.ppr and experimental_ppr flags are no longer needed.
- React Activity preserves component state during client navigation automatically.
Data fetching is dynamic by default under this model. You cache shared content with the directive and stream everything request-specific behind Suspense.
Node.js runtime required
Cache Components requires the Node.js runtime. The runtime = 'edge' export is deprecated, so remove it from any route before you enable the flag.
// app/api/data/route.ts
export const runtime = 'edge'Delete that line and the route runs on the Node.js runtime, which is what Cache Components expects. Other server-side JavaScript runtimes are not guaranteed to work.
Migrating from the old flags
Next.js 16 folds several experimental flags into this one. The mapping is straightforward:
| Old flag | In Next.js 16 |
|---|---|
| experimental.ppr | Removed, PPR is the default |
| experimental_ppr | Removed, PPR is the default |
| experimental.useCache | Replaced by cacheComponents |
| experimental.dynamicIO | Replaced by cacheComponents |
Delete the old keys from your config and keep cacheComponents. Static and dynamic rendering both still exist, but the default shifted toward a prerendered shell with streaming.
How to confirm it is on
Add the directive to a function and build. A cached function that reads no request data now joins the static shell.
// app/lib/posts.ts
import { cacheLife } from 'next/cache'
export async function getPosts() {
'use cache'
cacheLife('hours')
const res = await fetch('https://api.example.com/posts')
return res.json()
}The route that calls this function prerenders with the posts baked into its shell, and the entry revalidates every hour. Check the next build output: the route should be listed as prerendered rather than rendered on demand.
If the flag is missing, the directive is not silently ignored. The build fails and asks you to enable the cacheComponents feature flag in your Next.js config, which is the quickest way to confirm which model you are running.
Common mistakes
- Leaving the edge runtime on a route, which breaks the Node.js requirement.
- Expecting fetch to cache by default. It does not, you opt in with use cache.
- Enabling the flag but never adding the directive, so nothing changes.
For the directive itself, see the use cache directive. For how prerendering behaves under the new model, see Partial Prerendering.
Rune AI
Key Insights
- cacheComponents: true enables the Cache Components feature.
- Data becomes dynamic by default and caching is opt in.
- It replaces experimental.ppr, experimental_ppr, useCache, and dynamicIO.
- Partial Prerendering and React Activity become the default.
- It requires the Node.js runtime, not the edge runtime.
Frequently Asked Questions
What does cacheComponents replace?
Does Cache Components work on the Edge runtime?
Conclusion
Cache Components is a one-flag feature. Set cacheComponents to true, use the use cache directive on shared work, and remove any edge runtime exports. Partial Prerendering and React Activity then work by default.
More in this topic
`generateMetadata` Explained with Real Examples
What generateMetadata does, when it runs, and how to use it for real routes: awaited params, deduplicated data fetching, extending parent metadata, and returning a 404 from metadata.
Canonical URLs in Next.js: `metadataBase`, `alternates.canonical`, and Dynamic Pages
How canonical URLs work in the Next.js App Router: setting metadataBase once, writing alternates.canonical per route, handling dynamic segments, and what happens when the base URL is missing.
Open Graph and Twitter Card Metadata in Next.js
How to write Open Graph and Twitter card metadata in the Next.js App Router: the openGraph and twitter fields, automatic card defaults, article tags, and image merge rules.