home / skills / first-fluke / fullstack-starter / cache-components
This skill guides you to implement Next.js Cache Components and Partial Prerendering, optimizing caching decisions and data fetching for server components.
npx playbooks add skill first-fluke/fullstack-starter --skill cache-componentsReview the files below or copy the command above to add this skill to your agents.
---
name: cache-components
description: Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). PROACTIVE ACTIVATION when cacheComponents config is detected.
---
Expert guidance for Next.js Cache Components and Partial Prerendering (PPR).
**PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their `next.config.ts` or `next.config.js`.
**DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in `next.config`. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions.
**USE CASES**:
- Implementing `'use cache'` directive
- Configuring cache lifetimes with `cacheLife()`
- Tagging cached data with `cacheTag()`
- Invalidating caches with `updateTag()` / `revalidateTag()`
- Optimizing static vs dynamic content boundaries
- Debugging cache issues
- Reviewing Cache Component implementations
## Project Detection
When starting work in a Next.js project, check if Cache Components are enabled:
```bash
# Check next.config.ts or next.config.js for cacheComponents
grep -r "cacheComponents" next.config.* 2>/dev/null
```
If `cacheComponents: true` is found, apply this skill's patterns proactively when:
- Writing React Server Components
- Implementing data fetching
- Creating Server Actions with mutations
- Optimizing page performance
- Reviewing existing component code
## Core Concept: The Caching Decision Tree
When writing a **React Server Component**, ask:
1. **Does it depend on request context?** (cookies, headers, searchParams)
2. **Can this be cached?** (Is the output the same for all users?)
- **YES** -> `'use cache'` + `cacheTag()` + `cacheLife()`
- **NO** -> Wrap in `<Suspense>` (dynamic streaming)
## Philosophy: Code Over Configuration
Cache Components represents a shift from segment-based configuration to compositional code:
- **Before (Deprecated)**: `export const revalidate = 3600`
- **After**: `cacheLife('hours')` inside `'use cache'`
- **Before (Deprecated)**: `export const dynamic = 'force-static'`
- **After**: Use `'use cache'` and Suspense boundaries
## Quick Start
### 1. Enable Configuration
```typescript
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
ppr: true,
dynamicIO: true, // often correlated features
},
// Ensure basic cache components flag if required by your version
};
export default nextConfig;
```
### 2. Basic Usage
```typescript
import { cacheLife } from 'next/cache';
async function CachedPosts() {
'use cache'
cacheLife('hours'); // Cache for hours
const posts = await db.posts.findMany();
return <PostList posts={posts} />;
}
```
## Core APIs
### `'use cache'`
Marks a function, component, or file as cacheable. The return value is cached and shared across requests.
### `cacheLife(profile)`
Control cache duration using semantic profiles:
- `'seconds'`: Short-lived
- `'minutes'`: Medium-lived
- `'hours'`: Long-lived
- `'days'`: Very long-lived
- `'weeks'`: Static-like content
- `'max'`: Permanent cache
### `cacheTag(...tags)`
Tag cached data for on-demand invalidation.
```typescript
import { cacheTag } from 'next/cache';
async function getUserProfile(id: string) {
'use cache'
cacheTag('user-profile', `user-${id}`);
// ... fetch logic
}
```
### `revalidateTag(tag)` / `expireTag(tag)`
Invalidate cached data in background or immediately.
```typescript
'use server'
import { expireTag } from 'next/cache';
export async function updateUser(id: string, data: any) {
await db.user.update({ where: { id }, data });
expireTag(`user-${id}`); // Invalidate specific cache
}
```
This skill provides expert guidance for using Next.js Cache Components and Partial Prerendering (PPR). It activates proactively when a project’s next.config contains cacheComponents: true and guides component authoring, data fetching, tagging, and invalidation patterns. The goal is predictable caching behavior and clear guidance for static vs dynamic boundaries.
At session start it detects cacheComponents: true in next.config and applies a decision tree for React Server Components: determine request-context dependency, then choose caching or dynamic streaming. It recommends using the 'use cache' directive with cacheLife() and cacheTag() for cacheable outputs, and Suspense/dynamic streaming for request-specific content. It also covers server actions that mutate data and how to invalidate caches with expireTag() / revalidateTag().
How do I decide between cacheLife profiles?
Choose based on expected content volatility: seconds for fast-changing data, hours for often-read but occasionally-updated content, weeks/max for static assets.
What if a component sometimes needs request context?
Split it: keep the cacheable portion with 'use cache' and render the request-specific part inside a Suspense or client component.
When should I use tags vs global invalidation?
Prefer tags for targeted invalidation (by resource id/type). Global invalidation is only for sweeping changes like schema migrations.