Agent skill

Nextjs

by ericrisco in ericrisco/rsc-harness

A skill your agent uses when building, reviewing, testing, securing, or optimizing a Next.js App Router app: Server vs Client boundaries, use server actions, route handlers, the v15 vs v16 use cache…

MITAuto-check passedFrontend & Design

Install Nextjs

skills CLI
$ npx skills add ericrisco/rsc-harness --skill nextjs -a claude-code

Project install by default; add -g for ~/.claude/skills/.

GitHub CLI
$ gh skill install ericrisco/rsc-harness nextjs --agent claude-code

Project scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).

Manual copy
$ git clone --depth 1 https://github.com/ericrisco/rsc-harness.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/nextjs .claude/skills/nextjs && rm -rf skills-src

Use ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.

Claude Code skills documentation · loads skills from .claude/skills/

Facts

Skill name
nextjs
GitHub stars
167
Token cost
~5.1k tokens
SKILL.md length
1,544 words
Files
10 (incl. scripts, references)
Skills in repo
227
Repo updated
First seen
Licence
MIT

At a glance

A skill your agent uses when building, reviewing, testing, securing, or optimizing a Next.js App Router app: Server vs Client boundaries, use server actions, route handlers, the v15 vs v16 use cache…

  • Works in 4 steps: Read package.json → the next version. → Read next.config.{ts,js,mjs} for… → proxy.ts at the root ⇒ v16;… → …
  • Optimizing a Next.js App Router app: Server vs Client boundaries
  • SKILL.md covers First: detect the project's…, The boundary: Server vs Client…, "use server": Server Actions and Route Handlers (route.ts), plus 11 more sections
  • Runs Shell scripts from its folder; calls bash and tsc; needs NEXT_PUBLIC_API_KEY

What it does

Nextjs is an agent skill from ericrisco/rsc-harness. Use when building, reviewing, testing, securing, or optimizing a Next.js App Router app: Server vs Client boundaries, use server actions, route handlers, the v15 vs v16 use cache caching model, metadata/SEO, auth, and Core Web Vitals. NOT framework-agnostic React or a Vite SPA (that is react), and NOT visual/UI design (that is design).

Its SKILL.md is about 5.1k tokens, which your agent loads only when the skill is triggered. The skill folder holds 12 other files, including scripts and reference files (for example `evals/README.md`, `evals/cases.yaml` and `references/data-and-caching.md`).

It sits in Frontend & Design, covering Caching, UI design and Web performance. It works with Next.js, React and Vite. The repository describes itself as: Your agent invents things because it has no memory, and can't touch your database because it has no arms. rsc is the meta-harness that gives it both, plus the trade to know the… The licence is MIT.

When your agent uses it

  • Optimizing a Next.js App Router app: Server vs Client boundaries
  • Use server actions
  • The v15 vs v16 use cache caching model
  • Core Web Vitals

Example prompts

  • “/nextjs”

Requirements

  • A Bash shell

Workflow steps

4 steps, taken from the first numbered list in SKILL.md.

  1. Read package.json → the next version.
  2. Read next.config.{ts,js,mjs} for cacheComponents, ppr, reactCompiler, experimental.
  3. proxy.ts at the root ⇒ v16; middleware.ts ⇒ v15 (or v16 not yet migrated).
  4. cacheComponents: true OR any "use cache" in the tree ⇒ Cache Components model (opt-in

What it can do on your machine

Read from SKILL.md and the folder at commit e3d5b33. It shows what the files ask for, not the result of running them.

  • Tool permissions

    Pre-approves nothing: there is no allowed-tools line, so your agent's usual permission prompts apply.

    From allowed-tools in the SKILL.md frontmatter.

  • Runs code

    Ships 1 file in scripts/ (Shell), which the agent can run.

    Shell commands in SKILL.md call:

    • bash
    • tsc

    From the folder's file list and the shell code blocks in SKILL.md.

  • Network

    No URLs in SKILL.md.

    From URLs in SKILL.md, links to its own repository left out.

  • Credentials

    Names these keys or tokens, usually read from environment variables:

    • NEXT_PUBLIC_API_KEY

    From names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.

Context cost

Nextjs loads about 5.1k tokens when it runs, and up to ~21k if it reads all its reference files. Until then it costs about 88 tokens; SKILL.md has 1,544 words of instructions outside code blocks.

Always · name and description, kept in context so the agent knows when to use it
~88
When it runs · the whole SKILL.md, loaded when a task matches
~5.1k
With references · SKILL.md plus every file in references/, read only if the agent opens them
~21k

Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.

Safety

Auto-check passed

The automated check found no risky patterns in SKILL.md.

Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); the scripts in this folder are not scanned.

SKILL.md

The full file from ericrisco/rsc-harness at commit e3d5b33, republished under its MIT licence (© ericrisco). 1,544 words, ~5,145 tokens.

Download SKILL.mdSave it as .claude/skills/nextjs/SKILL.md (or your agent's skills folder). This skill also uses 9 other files; get the full folder from GitHub.
name
nextjs
description
Use when building, reviewing, testing, securing, or optimizing a Next.js App Router app: Server vs Client boundaries, `use server` actions, route handlers, the v15 vs v16 `use cache` caching model, metadata/SEO, auth, and Core Web Vitals. NOT framework-agnostic React or a Vite SPA (that is `react`), and NOT visual/UI design (that is `design`).
tags
nextjs, react, frontend, web, seo, ssr
recommends
design, secure-coding, deployment
origin
risco

Next.js App Router — RSC, Server Actions, React 19, TypeScript

Build, review, test, secure and optimize App Router apps, handling both the Next.js 15 (uncached-by-default) and Next.js 16 (use cache) caching models correctly.

SDD gate — read before writing code. If this fired on a new, non-trivial feature or behaviour change and there is no approved spec + plan under 02-DOCS/wiki/sdd/, STOP and hand off to ../specify/SKILL.md (brainstorm → spec → plan → tasks); it routes back here once the plan is approved. Build directly only for a genuinely one-line / low-risk change. Method: ../sdd/SKILL.md.

Not this skill: Pages Router (pages/) — note the difference, defer to the Next.js Pages docs. A pure React SPA (Vite/CRA) → ../react/SKILL.md; React Native / Expo → ../react-native/SKILL.md; a generic React question with no Next/RSC dimension → keep it brief, from references/react.md. Non-Next backends → ../fastapi/SKILL.md, ../go/SKILL.md; the data layer behind the DAL → ../postgresdb/SKILL.md; framework-agnostic security → ../secure-coding/SKILL.md, complemented here, never duplicated.

First: detect the project's version & caching model

Run this before prescribing or reviewing any caching, middleware, or React-Compiler behavior. Never mix v15 and v16 advice.

  1. Read package.json → the next version.
  2. Read next.config.{ts,js,mjs} for cacheComponents, ppr, reactCompiler, experimental.
  3. proxy.ts at the root ⇒ v16; middleware.ts ⇒ v15 (or v16 not yet migrated).
  4. cacheComponents: true OR any "use cache" in the tree ⇒ Cache Components model (opt-in caching). Otherwise ⇒ v15 model (uncached fetch by default, revalidate/tags).

Do not flag proxy.ts, use cache, or cacheComponents as errors — they are correct on Next.js 16.

Signal in repoModelCaching API to use
cacheComponents: true or any "use cache"Cache Components (v16)"use cache" + cacheLife() + cacheTag()/updateTag()
middleware.ts, no cacheComponentsv15 baselinefetch(..., { next: { revalidate, tags } }), unstable_cache, revalidateTag
proxy.ts presentv16 routingmiddleware logic lives in proxy.ts (NOT a security boundary)
reactCompiler: trueCompiler ondrop manual useMemo/useCallback/React.memo (review-only)

The boundary: Server vs Client Components

Default is a Server Component (async, can touch the DB and secrets, ships zero JS). Opt into a Client Component only for state, effects, event handlers, or browser APIs.

The four boundary laws:

  • Server → Client: pass serializable props or children (no functions except Server Actions).
  • Never import a Server Component into a Client Component; compose via children.
  • "use client" marks a module and its whole import subtree as client.
  • Keep "use client" leaves small; push the directive down the tree.
tsx
// app/projects/[id]/page.tsx — Good: server async page + a tiny client island
import { getProject } from "@/lib/dal";
import { LikeButton } from "./like-button";

export default async function Page({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  const project = await getProject(id); // DB call stays on the server
  return (
    <main>
      <h1>{project.name}</h1>
      <LikeButton projectId={project.id} initialLikes={project.likes} />
    </main>
  );
}

When a Client Component needs server content, give it a children (or prop) slot and pass the Server Component from a server parent — <ClientPanel><ServerChart /></ClientPanel>. The import-graph rule and the full Bad/Good contrast are in references/react.md (Server vs Client deep dive).

"use server": Server Actions

Every Server Action is a public POST endpoint. It MUST authenticate and authorize itself. Middleware/proxy does NOT protect it.

ts
// app/projects/actions.ts
"use server";
import { z } from "zod";
import { revalidateTag } from "next/cache";
import { auth } from "@/auth";
import { db } from "@/lib/db";

const RenameSchema = z.object({ id: z.string().uuid(), name: z.string().min(1).max(120) });

type RenameResult =
  | { status: "ok"; data: { id: string; name: string } }
  | { status: "error"; message: string };

export async function renameProject(_prev: RenameResult | null, formData: FormData): Promise<RenameResult> {
  const session = await auth();
  if (!session?.user) return { status: "error", message: "Not authenticated" };

  const parsed = RenameSchema.safeParse(Object.fromEntries(formData));
  if (!parsed.success) return { status: "error", message: "Invalid input" };

  const owned = await db.project.findFirst({ where: { id: parsed.data.id, ownerId: session.user.id } });
  if (!owned) return { status: "error", message: "Forbidden" };

  const updated = await db.project.update({ where: { id: parsed.data.id }, data: { name: parsed.data.name } });
  revalidateTag(`project:${updated.id}`);
  return { status: "ok", data: { id: updated.id, name: updated.name } };
}

Two invocation modes: <form action={renameProject}> — progressive enhancement, works without JS — or imperative from a client handler wrapped in startTransition(() => renameProject(null, fd)).

Route Handlers (route.ts)

Use a Route Handler for: webhooks, a public JSON API, OAuth callbacks, streaming responses, and non-form clients. Use a Server Action instead for internal form mutations. GET handlers are uncached by default on v15 (control with export const dynamic / runtime), and every handler — GET included — runs its own auth() check and scopes reads to the session user.

ts
// app/api/projects/route.ts
import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { auth } from "@/auth";
import { db } from "@/lib/db";

const CreateSchema = z.object({ name: z.string().min(1).max(120) });

export async function POST(req: NextRequest) {
  const session = await auth();
  if (!session?.user) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
  const parsed = CreateSchema.safeParse(await req.json());
  if (!parsed.success) return NextResponse.json({ error: parsed.error.flatten() }, { status: 422 });
  const created = await db.project.create({ data: { name: parsed.data.name, ownerId: session.user.id } });
  return NextResponse.json({ project: created }, { status: 201 });
}

Layouts, templates, loading & error boundaries

FileRole / when it runs
layout.tsxWraps a segment; persists across navigation, does NOT remount
template.tsxLike layout but remounts on every navigation (fresh state)
loading.tsxInstant Suspense fallback for the segment while it streams
error.tsx"use client" error boundary for the segment, gets reset()
not-found.tsxRendered by notFound() and unmatched routes
global-error.tsxReplaces the root layout when the root throws

An error.tsx is always "use client", receives { error: Error & { digest?: string }, reset }, and should render role="alert" plus a button calling reset().

tsx
// app/dashboard/page.tsx — Good: stream the shell, Suspense the slow part
import { Suspense } from "react";
import { Stats } from "./stats";

export default function Page() {
  return (
    <main>
      <h1>Dashboard</h1>
      <Suspense fallback={<p>Loading stats…</p>}>
        <Stats /> {/* async Server Component; the shell paints immediately */}
      </Suspense>
    </main>
  );
}

Routing: groups, parallel, intercepting, dynamic, metadata

  • Route groups (marketing)/ organize without affecting the URL; dynamic [id], catch-all [...slug], optional [[...slug]].
  • params and searchParams are Promises on v15+ — await them.
  • Parallel routes @modal + default.tsx; intercepting (.)photo — modal-on-navigation.
  • generateMetadata (async) + generateStaticParams.
tsx
// Bad: treating params as a plain object (the top v15-migration bug)
function PageBad({ params }: { params: { id: string } }) {
  return <h1>{params.id}</h1>; // runtime/type error on v15+
}
// Good: params is a Promise — await it
async function PageGood({ params }: { params: Promise<{ id: string }> }) {
  const { id } = await params;
  return <h1>{id}</h1>;
}

Metadata & SEO

The App Router emits <title>, <meta>, OpenGraph/Twitter tags, sitemap.xml, and robots.txt from code (identical API on v15/v16). Build-side patterns → references/metadata.md; the strategy side — JSON-LD, GEO, keyword research — is ../marketing/SKILL.md's (../marketing/references/seo-geo.md): this skill emits the tags, that one picks the content.

  • metadata/generateMetadata are Server-Component-only — one or the other per file (static object when known at build; async generateMetadata when it depends on params/data, wrapped in React.cache to dedupe with the page). Set metadataBase once in the root layout so relative OG/canonical URLs resolve to absolute.
  • app/sitemap.ts → MetadataRoute.Sitemap (50k-URL cap; shard with generateSitemaps() past that); app/robots.ts → MetadataRoute.Robots (link the sitemap, disallow private paths).
  • Dynamic OG images: opengraph-image.tsx returning ImageResponse from next/og (flexbox-only CSS).
tsx
// app/blog/[slug]/page.tsx — dynamic metadata + OpenGraph (sitemap.ts/robots.ts/next/og in references/metadata.md)
import type { Metadata } from "next";
import { getPost } from "@/lib/dal";

export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise<Metadata> {
  const { slug } = await params; // params is a Promise on v15+
  const post = await getPost(slug); // React.cache-shared with the page
  if (!post) return {};
  return {
    title: post.title,
    description: post.excerpt,
    alternates: { canonical: `/blog/${slug}` },
    openGraph: {
      title: post.title,
      type: "article",
      images: [{ url: post.cover, width: 1200, height: 630, alt: post.title }], // recommended OG size
    },
    twitter: { card: "summary_large_image", title: post.title },
  };
}

Caching & data fetching (both models)

Which block applies is decided by the detection gate above. Optimistic UI, useActionState + zod forms and the full mutation patterns are in references/data-and-caching.md.

v15 model — fetch is uncached by default; opt in explicitly.

ts
// uncached on v15 (re-fetched every request):
const live = await fetch("https://api.example.com/now").then((r) => r.json());

// opt into the data cache + tag it:
const products = await fetch("https://api.example.com/products", {
  next: { revalidate: 3600, tags: ["products"] },
}).then((r) => r.json());

// from a Server Action: invalidate the tag (or a route with revalidatePath)
import { revalidateTag } from "next/cache";
revalidateTag("products");

// request-scoped dedupe (one query per render); see also unstable_cache + route segment config
import { cache } from "react";
export const getUser = cache(async (id: string) => db.user.findUnique({ where: { id } }));

v16 Cache Components — everything dynamic by default; opt in with "use cache".

ts
// lib/products.ts — Next.js 16: cacheLife/cacheTag/updateTag are STABLE (no unstable_ prefix;
// the v15 preview used `unstable_cacheLife as cacheLife`, `unstable_cacheTag as cacheTag`).
import { cacheLife, cacheTag, updateTag } from "next/cache";

export async function getProducts() {
  "use cache";
  cacheLife("hours");
  cacheTag("products");
  return db.product.findMany();
}

// from a Server Action: updateTag = immediate read-your-writes;
// revalidateTag("products", "hours") = stale-while-revalidate. See references/data-and-caching.md.
updateTag("products");
ts
// Bad: reading request APIs inside "use cache" hangs/errors the build
export async function getCartBad() {
  "use cache";
  const c = await cookies(); // ✗ not allowed inside use cache
  return db.cart.find(c.get("cartId")?.value);
}

// Good: read the request value OUTSIDE, pass it as an argument
export async function getCart(cartId: string) {
  "use cache";
  cacheTag(`cart:${cartId}`);
  return db.cart.find(cartId);
}

React 19 in the App Router (essentials)

The Next-relevant deltas (full discipline, hooks, state-location tree, composition → references/react.md): useActionState(fn, initial) → [state, action, isPending] (replaces useFormState); useFormStatus() for a child submit button; useOptimistic auto-reverts on action error; use(promise) unwraps an RSC-passed Promise under <Suspense>; ref is a normal prop (no forwardRef); <Context value> is the provider; React Compiler on (reactCompiler: true) ⇒ drop manual memoization.

tsx
"use client";
import { useActionState } from "react";
import { renameProject } from "./actions"; // the "use server" action defined above

export function RenameForm({ id }: { id: string }) {
  const [state, action, isPending] = useActionState(renameProject, null);
  return (
    <form action={action}>
      <input type="hidden" name="id" value={id} />
      <input name="name" aria-label="Project name" required />
      <button disabled={isPending}>{isPending ? "Saving…" : "Save"}</button>
      {state?.status === "error" && <p role="alert">{state.message}</p>}
    </form>
  );
}

TypeScript discipline

  • strict: true + noUncheckedIndexedAccess: true.
  • Typed routes (typedRoutes: true, or experimental.typedRoutes on older v15).
  • zod-inferred end-to-end types (z.infer) shared across action input, form, and DB layer.
  • Discriminated-union action result { status: "ok"; data } | { status: "error"; message }.
  • params/searchParams typed as Promise<...>.
ts
// Bad: untyped form data
const data: any = Object.fromEntries(formData);

// Good: validate + infer one shared type
const schema = z.object({ name: z.string().min(1), email: z.string().email() });
type Input = z.infer<typeof schema>; // reuse for form + DB layer
const r = schema.safeParse(Object.fromEntries(formData));
if (!r.success) return { status: "error", message: "Invalid" };
Show full SKILL.md (634 more words)Show less

Auth & security (deep dive → references/security.md)

Defense in depth with three layers — middleware is NOT one of them. Full wiring (Auth.js v5 auth.ts, the DAL, CSRF, cookies, CSP, SSRF) lives in references/security.md; apply this checklist on every review:

  • proxy.ts/middleware.ts is a coarse redirect only (NOT a security boundary).
  • auth() check inside every Server Action and Route Handler (shown in those sections above); re-check the session in a Data Access Layer (DAL) before any read/write — the DAL is the real boundary.
  • Secure cookies: httpOnly, secure, sameSite: "lax"; rotate the session on any privilege change.
  • CSRF: Server Actions verify Origin/Host; never expose a mutation as an unauthenticated GET; set serverActions.allowedOrigins in next.config.ts.
  • Never put secrets in NEXT_PUBLIC_* — they ship to the browser; proxy via a Route Handler and mark server-only modules with import 'server-only'.
  • SSRF: allowlist host/scheme before fetch in Route Handlers; block internal/metadata ranges.
  • CSP with a nonce via proxy.ts/headers. See also ../secure-coding/SKILL.md.

Performance (deep dive → references/performance.md)

  • next/image — always width/height or fill + a sized parent; priority on the LCP image; sizes.
  • next/font — self-host, display: "swap", subset → zero CLS + no extra round-trip.
  • next/dynamic for heavy client islands; optimizePackageImports; @next/bundle-analyzer.
  • Kill waterfalls with parallel Promise.all / split sibling fetches into parallel children; PPR/streaming, reserve space to avoid CLS.
  • Long lists: content-visibility: auto + virtualize (@tanstack/react-virtual) past ~50 rows; warm assets with react-dom preload/preconnect; narrow store selectors (Zustand) cut re-renders. Full lever→metric map in references/performance.md.
  • Core Web Vitals targets: LCP < 2.5s, CLS < 0.1, INP < 200ms (INP replaced FID).

Anti-patterns

Common beliefReality / STOP
"The client already checks the user, the action is safe"Server Actions are public POST endpoints — authenticate inside the action
"fetch caches by default, skip revalidate"v15: fetch is uncached by default; that's the v13/14 mental model
"Read cookies() inside use cache for convenience"Build hangs/errors; read outside, pass the value as an argument
"proxy.ts looks misnamed, rename to middleware.ts"Correct on v16; renaming breaks middleware execution
"Just import the Server Component into this client file"Compose via children; importing forces it client / breaks the build
"Put the API key in NEXT_PUBLIC_API_KEY"It ships to the browser; proxy through a Route Handler/Server Action
"Add useMemo everywhere for perf"Measure first; with React Compiler manual memoization is noise
"await params is unnecessary"v15+: params/searchParams are Promises — you must await
"Middleware protects my dashboard, the data fetch is safe"Middleware is not a security boundary; check in the DAL
"Snapshot-test the RSC page"Async Server Components aren't jsdom-renderable; test data fns + Playwright

Verify

Run bash scripts/verify.sh from the Next.js project root. It runs ESLint, tsc --noEmit, Vitest, and next build, skipping any tool not installed (a missing tool is a yellow warning, never a failure). It reads the installed Next.js major version and only falls back to next lint on v15 and earlier — next lint was removed in v16, so on a v16 repo a missing ESLint is a SKIP, never a false failure. The lint/type/test steps are read-only; the final next build writes the .next/ output directory. No installs, no network mutations. Safe to re-run.

Test strategy — Vitest 3 + RTL + MSW 2 for units, Playwright for pages, and the RSC testing reality behind that last anti-pattern row: references/testing.md.

Project grounding (02-DOCS + CLAUDE.md)

In a project with a 02-DOCS/ layer (the harness Karpathy wiki), this project's app decisions live in 02-DOCS/wiki/stack/nextjs.md, indexed from 02-DOCS/wiki/index.md (the Knowledge map; root CLAUDE.md keeps only a pointer). Read it first on every use and stay consistent. Missing or stale → write the project's real choices there — caching model in use (v15 fetch-cache vs v16 use cache), auth approach, server-action and data-fetching conventions, runtime (edge/node), design-system hookup — index it, and bump its Updated date in the same change as any convention change. No 02-DOCS/ layer? Skip silently (optionally suggest harness). Unlike the brand study, technical conventions are recorded, not gated — never block the task on this.

© ericrisco, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file

Files

SKILL.md and 9 other files (scripts, references) in skills/nextjs of ericrisco/rsc-harness.

  • SKILL.md
  • evals/README.md
  • evals/cases.yaml
  • references/data-and-caching.md
  • references/metadata.md
  • references/performance.md
  • references/react.md
  • references/security.md
  • references/testing.md
  • scripts/verify.sh

Open the folder on GitHubat commit e3d5b33

Compare with similar skills

Nextjs next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.

Nextjs compared with similar skills
SkillStarsUsed inTokensAuto-checkLicenceRepo updated
Nextjs this skillericrisco/rsc-harness167—~5.1kAutomated safety check: PassMIT
Creative Tim UI Blockscreativetimofficial/ui12k—~2.1kAutomated safety check: NotesMIT
React Best Practicesryokun6/ryos1.3k—~2kAutomated safety check: PassMIT
Frontend Engineer Workflownanocoai/nanoclaw31k—~1.5kAutomated safety check: PassMIT
Nextjs Performancegiuseppe-trisciuoglio/developer-kit355—~3.2kAutomated safety check: NotesMIT
Add React Analyticsgotempsh/temps826—~2.7kAutomated safety check: PassApache-2.0

Similar skills

  • Creative Tim UI Blocks

    creativetimofficial/ui

    Helps install, generate and review Creative Tim UI blocks: shadcn/ui-based React and Tailwind sections that follow a restrained, production-minded design philosophy.

    12k GitHub stars~2.1k tokensUpdated 6 mo ago
    Frontend & DesignAuto-check: notes
  • React performance optimization guidelines from Vercel Engineering (vercel-labs/agent-skills).

    1.3k GitHub stars~2k tokensUpdated today
    Frontend & DesignAuto-check passed
  • Sets a build, test and verify routine for web projects: write typed, accessible code and never call work done until it is checked in a real browser with screenshots.

    31k GitHub stars~1.5k tokensUpdated yesterday
    Frontend & DesignAuto-check passed
  • Nextjs Performance

    giuseppe-trisciuoglio/developer-kit

    Expert Next.js performance optimization skill covering Core Web Vitals, image/font optimization, caching strategies, streaming, bundle optimization, and Server Components best practices.

    355 GitHub stars~3.2k tokensUpdated 27 days ago
    Frontend & DesignAuto-check: notes
  • Add React Analytics

    gotempsh/temps

    Add Temps analytics to React applications with comprehensive tracking capabilities including page views, custom events, scroll tracking, engagement monitoring, session recording, and Web Vitals…

    826 GitHub stars~2.7k tokensUpdated today
    DevOps & CloudAuto-check passed
  • Liteyuki Webui Frontend

    LiteyukiStudio/LiteyukiBot

    Build, review, or test LiteyukiBot v7's React/Vite WebUI under webui/ and its packaged static delivery in packages/webui/.

    157 GitHub stars~2.5k tokensUpdated 1 mo ago
    Frontend & DesignAuto-check passed

More from ericrisco/rsc-harness

All 227 skills in this repo
  • Ab Testing

    ericrisco/rsc-harness

    A skill your agent uses when designing or analyzing a controlled experiment — falsifiable hypothesis, sample size from an MDE, reading significance/CI/power, CUPED, or rescuing tests that won't go…

    167 GitHub stars~2.4k tokensUpdated today
    Auto-check passed
  • Accessibility

    ericrisco/rsc-harness

    A skill your agent uses when making a web UI conform to WCAG 2.2 Level AA — axe-core or Lighthouse a11y violations, keyboard operability, focus management, ARIA roles/names/live regions, contrast…

    167 GitHub stars~3.4k tokensUpdated today
    Auto-check passed
  • Ads

    ericrisco/rsc-harness

    A skill your agent uses when running or fixing paid acquisition on Google or Meta — campaign structure (Performance Max, Demand Gen, Search, Advantage+), platform-fit creative, budget/scaling rules…

    167 GitHub stars~2.2k tokensUpdated today
    Auto-check passed
  • Agent Eval

    ericrisco/rsc-harness

    A skill your agent uses when measuring whether an LLM or agent system actually got better and gating merges on it: golden sets, fixing an inflated LLM-as-judge, scoring RAG (faithfulness, contextual…

    167 GitHub stars~3.2k tokensUpdated today
    Auto-check passed
  • AI Media

    ericrisco/rsc-harness

    A skill your agent uses when a creative goal must become a finished media file: pick and order generative-media models per modality — AI voiceover, image-to-video clips, score — then glue them with…

    167 GitHub stars~3.3k tokensUpdated today
    Auto-check passed
  • Analytics

    ericrisco/rsc-harness

    A skill your agent uses when instrumenting product or web analytics — GA4/PostHog SDK wiring, event taxonomy, funnels, double-counted events, consent gating, PII scrubbing.

    167 GitHub stars~2.8k tokensUpdated today
    Auto-check passed

Questions about Nextjs

What does Nextjs do?

A skill your agent uses when building, reviewing, testing, securing, or optimizing a Next.js App Router app: Server vs Client boundaries, use server actions, route handlers, the v15 vs v16 use cache…. Nextjs is an agent skill from ericrisco/rsc-harness.js App Router app: Server vs Client boundaries, use server actions, route handlers, the v15 vs v16 use cache caching model, metadata/SEO, auth, and Core Web Vitals.

When should I use Nextjs?

Nextjs fits situations like: optimizing a Next.js App Router app: Server vs Client boundaries; use server actions; the v15 vs v16 use cache caching model; core Web Vitals.

How do I install Nextjs in Claude Code?

Run `npx skills add ericrisco/rsc-harness --skill nextjs -a claude-code`. Or copy the skill folder (skills/nextjs in ericrisco/rsc-harness) into .claude/skills/nextjs in your project. Claude Code loads it when a task matches its description.

How do I install Nextjs in Codex?

Run `npx skills add ericrisco/rsc-harness --skill nextjs -a codex`. Or copy the skill folder (skills/nextjs in ericrisco/rsc-harness) into .agents/skills/nextjs in your project. Codex loads it when a task matches its description.

Can I use Nextjs in Cursor, Gemini CLI or GitHub Copilot?

Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add ericrisco/rsc-harness --skill nextjs -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/nextjs, .gemini/skills/nextjs, .github/skills/nextjs and .opencode/skills/nextjs in your project.

What does Nextjs need to run?

Going by SKILL.md and its folder, Nextjs needs a shell for the scripts in its folder, the command-line tools its instructions call (bash and tsc) and credentials named NEXT_PUBLIC_API_KEY. Our summary lists: A Bash shell.

Does Nextjs access the network?

SKILL.md contains no URLs. Any network use would come from the scripts or tools the agent runs. This is read from the text; nothing was executed.

Is Nextjs safe to install?

Our automated static check of SKILL.md found no risky patterns, such as piping downloads into a shell, reading credential files or hidden Unicode. It is not a guarantee. The check reads SKILL.md only: the scripts in the folder are not scanned, so read them before running anything.

What licence does Nextjs use?

Nextjs is published under the MIT licence (the repository's licence). It allows redistribution, so the full SKILL.md is shown on this page.

How many tokens does Nextjs use?

About 5.1k tokens (SKILL.md is roughly 21k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 16k tokens, read only when the agent opens those files.

What are the alternatives to Nextjs?

Skills that share tags, products or a category with Nextjs: Creative Tim UI Blocks (creativetimofficial/ui, 12k stars), React Best Practices (ryokun6/ryos, 1.3k stars), Frontend Engineer Workflow (nanocoai/nanoclaw, 31k stars) and Nextjs Performance (giuseppe-trisciuoglio/developer-kit, 355 stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.

Who maintains Nextjs?

ericrisco (a GitHub user) maintains it in ericrisco/rsc-harness, which has 167 GitHub stars. The repository holds 227 skills in this directory. The repository was last updated on October 7, 2026.

Source: ericrisco/rsc-harness on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.