
Nextjs Performance
Ship faster Next.js App Router API routes with caching, edge runtime, and streaming responses.
Overview
Next.js Performance is an agent skill for the Build phase that guides solo builders through optimized App Router route handlers, including caching exports, edge runtime, and streaming APIs.
Install
npx skills add https://github.com/giuseppe-trisciuoglio/developer-kit --skill nextjs-performanceWhat is this skill?
- App Router GET/POST route handler templates with `NextResponse.json` and status codes
- Static vs dynamic control via `dynamic`, `revalidate`, and error handling on POST
- Edge runtime setup with `runtime = 'edge'` and `preferredRegion` for lower cold starts
- Streaming POST responses on the edge for incremental or large payloads
- Copy-paste TypeScript patterns aligned with Next.js `app/` directory conventions
- Covers 4 route-handler patterns: base GET, POST, edge runtime, and streaming POST
Adoption & trust: 1.6k installs on skills.sh; 271 GitHub stars; 3/3 security scanners passed (skills.sh audits).
What problem does it solve?
You are adding Next.js `app/api` routes but are unsure how to set caching, edge vs Node, and streaming without hurting latency or correctness.
Who is it for?
Indie builders on Next.js App Router who need production API routes with edge or streaming and clear cache boundaries.
Skip if: Teams not on Next.js, pure static sites with no API routes, or deep Core Web Vitals work that needs only client-side bundle analysis.
When should I use this skill?
You are implementing or hardening Next.js App Router API routes and need caching, edge, or streaming patterns.
What do I get? / Deliverables
After applying the skill, you have tested route-handler templates with explicit `dynamic`/`revalidate`, edge or streaming setups, and JSON error shapes ready to merge into your repo.
- Optimized `app/api/**/route.ts` handlers with appropriate runtime and cache exports
- Edge or streaming endpoints with structured JSON success and error responses
Recommended Skills
Journey fit
Route handlers and runtime choices are implemented while building the Next.js product’s API layer, before launch tuning. The skill centers on `app/api` route handlers, data mutations, and response shaping—the backend surface of a Next.js app.
How it compares
Use for Next.js-specific route-handler recipes instead of generic REST framework tutorials that ignore `revalidate` and edge runtime.
Common Questions / FAQ
Who is nextjs-performance for?
Solo and indie developers shipping SaaS or API-backed sites on Next.js who implement `app/api` route handlers and want performance-oriented defaults.
When should I use nextjs-performance?
During Build when you create or refactor API routes; during Ship when you tune `revalidate`, edge regions, or streaming before release.
Is nextjs-performance safe to install?
Treat it as documentation patterns only—review the Security Audits panel on this Prism page and inspect the skill package in your repo before granting agent permissions.
SKILL.md
READMESKILL.md - Nextjs Performance
# Route Handlers Ottimizzati ## Overview Route handlers in `app/` directory per API endpoints con supporto streaming e edge runtime. --- ## Pattern Base ### GET Handler ```typescript // app/api/users/route.ts import { NextResponse } from 'next/server' export const dynamic = 'force-static' export const revalidate = 3600 export async function GET() { const users = await db.user.findMany() return NextResponse.json(users) } ``` ### POST Handler ```typescript // app/api/users/route.ts export async function POST(request: Request) { try { const body = await request.json() const user = await db.user.create({ data: body, }) return NextResponse.json(user, { status: 201 }) } catch (error) { return NextResponse.json( { error: 'Failed to create user' }, { status: 500 } ) } } ``` --- ## Edge Runtime ```typescript // app/api/edge/route.ts export const runtime = 'edge' export const preferredRegion = 'iad1' // US East export async function GET(request: Request) { const { searchParams } = new URL(request.url) const query = searchParams.get('q') // Edge runtime: minore cold start, distribuito globalmente const result = await fetch(`https://api.example.com/search?q=${query}`) return new Response(await result.text(), { headers: { 'content-type': 'application/json' }, }) } ``` --- ## Streaming Response ```typescript // app/api/stream/route.ts export const runtime = 'edge' export async function POST(request: Request) { const { prompt } = await request.json() const response = await fetch('https://api.openai.com/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', Authorization: `Bearer ${process.env.OPENAI_API_KEY}`, }, body: JSON.stringify({ model: 'gpt-4', messages: [{ role: 'user', content: prompt }], stream: true, }), }) // Stream la response direttamente return new Response(response.body, { headers: { 'Content-Type': 'text/event-stream' }, }) } ``` --- ## Caching Headers ```typescript // app/api/data/route.ts export async function GET() { const data = await fetchData() return NextResponse.json(data, { headers: { 'Cache-Control': 'public, s-maxage=60, stale-while-revalidate=300', }, }) } // Con ETag export async function GET(request: Request) { const data = await fetchData() const etag = generateETag(data) // Check If-None-Match if (request.headers.get('If-None-Match') === etag) { return new Response(null, { status: 304 }) } return NextResponse.json(data, { headers: { ETag: etag, 'Cache-Control': 'public, max-age=3600', }, }) } ``` --- ## Middleware ```typescript // middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { // CORS headers const response = NextResponse.next() response.headers.set('Access-Control-Allow-Origin', '*') response.headers.set('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS') response.headers.set('Access-Control-Allow-Headers', 'Content-Type, Authorization') // Rate limiting semplice const ip = request.ip ?? 'anonymous' const limit = await checkRateLimit(ip) if (!limit.success) { return new NextResponse('Rate limit exceeded', { status: 429 }) } return response } export const config = { matcher: '/api/:path*', } ``` --- ## Error Handling ```typescript // app/api/error-handler.ts import { NextResponse } from 'next/server' export class APIError extends Error { constructor( message: string, public statusCode: number = 500, public code: string = 'INTERNAL_ERROR' ) { super(message) } } export function handleError(error: unknown) { if (error instanceof APIError) { return NextResponse.json( { error: error.message, code: error.code }, { status: error.statusCode } ) } console.er