Skip to content
Development
Skill

/next-cache-components-optimizer

Drive a Next.js route to instant navigation by setting up an agentic loop, under Cache Components / PPR, on initial load (hard navigation) and client-side navigation (soft navigation). Encode the goal as a failing @next/playwright instant() e2e and work it to green, one verified

From plugin
nextjs
142k4 skills
Install
$ npx -y skills add vercel/next.js --skill next-cache-components-optimizer --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/next-cache-components-optimizer

Context preview

The summary Claude sees to decide when to auto-load this skill.

Drive a Next.js route to instant navigation by setting up an agentic loop, under Cache Components / PPR, on initial load (hard navigation) and client-side navigation (soft navigation). Encode the goal as a failing @next/playwright instant() e2e and work it to green, one verified

SKILL.md

next-cache-components-optimizer.SKILL.md
name: next-cache-components-optimizer
description: >
  Drive a Next.js route to instant navigation by setting up an agentic loop,
  under Cache Components / PPR, on initial load (hard navigation) and
  client-side navigation (soft navigation). Encode the goal as a failing
  @next/playwright instant() e2e and work it to green, one verified route at a
  time; the shipped test then guards against regression. Use when asked to make
  a route's navigation instant (its static shell commits immediately), fix a
  route whose static shell isn't prerendered/served/prefetched, grow a route's
  static shell or fix its slow first paint, diagnose which Suspense boundary
  keeps a route out of its static shell, or write the instant() e2e guard for
  one. Requires Next.js 16.3+ with cacheComponents; directs an upgrade if older.

next-cache-components-optimizer

Set up an agentic optimization loop that drives a Next.js route from "not instant" to "instant" and keeps it there. The loop is test-driven: encode the goal as a failing `@next/playwright` `instant()` test, work it to green, and ship the test as the regression guard. Run it once per target route. Work the phases P → G in order; each ends in a gate. Fix recipes live in two lazily-read references — `reference/patterns.md` (before→after for each blocker type) and `reference/real-app-patterns.md` (parallel routes, auth gates, the empty-shell and responsive-skeleton failure modes). Read one only when its phase points there.

What is invariant, and what is yours

One thing here is fixed. The rest is yours. Read this before treating any command, platform, or env var below as a requirement.

  • **Invariant: the verification loop.** Maximizing the shell is worthless

unless you can prove it. The proof is an automated check: under a lock that gates dynamic data, the static shell still commits. RED shows the gap, GREEN shows it closed, the test ships as the regression guard. It must run on a production-like build and must not be able to pass vacuously. Stand the loop up once; every later optimization is then verifiable by construction. The loop is the deliverable, not any one route.

  • **The mechanism: `@next/playwright` `instant()`.** This skill uses

[`instant()`](https://nextjs.org/docs/app/guides/instant-navigation#prevent-regressions-with-e2e-tests) as a ruler, not a stopwatch (phase A). It comes from `@next/playwright` (installed alongside `@playwright/test`, on the same release line as `next`), so it isn't tied to any host. Keep it. Timing a navigation by hand is too flaky to trust, and is the failure mode this skill exists to prevent.

  • **Yours: the rig.** How you build, deploy, authenticate, configure

Playwright, and loop belongs to your stack, not to this skill. A local `next build && next start`, a CI/staging container, and a per-push preview deploy are equally valid rigs; the verdict comes from the build, never the platform. Phase 0 maps the invariant onto your repo. Read every platform name, env-var spelling, and command below as an example to translate, not a requirement.

Two navigations, two loading states

A route reaches the user two ways, and both must be instant:

  • **Initial load (hard navigation)** commits the route's prerendered static

shell; deferred parts stream in behind their loading skeletons (Suspense fallbacks, `loading.tsx`).

  • **Client-side navigation (soft navigation)** commits the destination's

prefetched App Shell — the `<Link>` default under Partial Prefetching — re-rendering only the segments that change.

The fix patterns are identical for both; the test differs only in how the navigation is driven ("Driving the navigation in tests" below). The two shells can differ; guard the one you ship, both when both matter (`reference/real-app-patterns.md`).

Goal

Maximizing the static shell is the optimization objective: the most meaningful prerendered content commits immediately, and only genuinely per-request data streams in afterward. The shipped test deterministically encodes **present ∧ instant**; **non-blank** is the additional bar the workflow enforces by judgment (D1/D2/E), because an `instant()` pass alone is satisfied by a blank `fallback={null}` shell (the empty-shell failure mode, `reference/real-app-patterns.md`).

`instant()` is a ruler, not a stopwatch: assert that the shell appears under the lock; do not time it. A trustworthy verdict requires a production build (phase A).

The GREEN under the lock is the deterministic verdict; each gate keeps it trustworthy.

Reporting to the user

This loop is meant to run unattended, so it doesn't stop to ask between steps. Work the navigation the user named, finish it, and stop. What matters is how you word and present the results, not how often you interrupt. The mechanics below — the rig, RED, GREEN, the gates — are your scaffolding; the user never needs to hear those words.

  • **Speak their language.** Describe the gap and the result in terms of what the

user sees: "navigating to the dashboard waited on the charts query before anything painted; now the layout and skeletons paint instantly and the charts stream in" — not RED/GREEN, the lock, or the phase letters.

  • **Show, don't tell.** When you report a route, drive the browser (or attach

before/after screenshots) so the user watches the shell commit immediately and the data stream in, rather than reading a claim. Identical before and after means the fix did nothing — roll it back.

  • **Present a run as a list of results the user can click through** — one line

per navigation: the route, what commits instantly, and what streams in — not a transcript of the loop.

  • **Only surface a question for a genuine fork:** a fix that would change

behavior, a security-sensitive read, or a route that's dynamic by design (a runtime-prefetch candidate, not a shell to grow). A clean instant fix is not a fork — keep going. With no one to ask (an unattended run

Read more
Ships withnextjs

The React Framework

Get the whole plugin
Stats
141,711
Stars
31,722
Forks
Active
Maintenance
JavaScript
Language
MIT
License
1h ago
Last commit
9y ago
Created

Repo: vercel/next.js