Claude-skill-registry latest-nextjs
Latest React and Next.js features for past 1.5 years (mid-2024 to 2026)
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/latest-nextjs" ~/.claude/skills/majiayu000-claude-skill-registry-latest-nextjs && rm -rf "$T"
skills/data/latest-nextjs/SKILL.mdLatest React & Next.js Skill
Comprehensive knowledge of React and Next.js features from mid-2024 through 2025. This skill fills the gap between LLM training cutoffs and current knowledge, covering React 19.2 (October 2025), Next.js 16 (October 2025), and supporting ecosystem changes.
React 19.2 (Latest - October 2025)
Current Status
- Latest stable version: React 19.2 (released October 1, 2025)
- Previous updates: React 19.1 (March 2025 - refinement release)
- Initial release: React 19 (December 2024)
Key Improvements in 19.1-19.2
- No breaking changes from 19.0
- Performance optimizations
- Enhanced DevTools features
- 30-40% smaller JavaScript bundle sizes
- Faster TTFB (Time to First Byte)
React 19 Core Features
New Hooks
useOptimistic
useOptimisticManages optimistic UI updates during async mutations:
import { useOptimistic } from "react"; function LikeButton({ postId, initialLiked }) { const [optimisticLiked, addOptimistic] = useOptimistic( initialLiked, (state, newLiked) => !state ); async function handleToggle() { addOptimistic(!optimisticLiked); await toggleLike(postId); } return ( <button onClick={handleToggle}> {optimisticLiked ? "Unlike" : "Like"} </button> ); }
Use cases: Like buttons, todo lists, any UI showing predicted state during server updates.
useActionState
useActionStateConnects forms to action functions and tracks response state:
import { useActionState } from "react"; const [state, formAction, isPending] = useActionState( async (prevState, formData) => { const email = formData.get("email"); await subscribe(email); return { success: true, message: "Subscribed!" }; }, null );
Replaces: Manual form state management, loading states, error handling.
useFormStatus
useFormStatusAccesses parent form status from nested components:
import { useFormStatus } from "react"; function SubmitButton() { const { pending, data, method, action } = useFormStatus(); return ( <button disabled={pending}>{pending ? "Sending..." : "Submit"}</button> ); }
Key use case: Submit buttons that need parent form state.
Enhanced useTransition
useTransitionNow supports async functions with automatic state management:
const [isPending, startTransition] = useTransition(); startTransition(async () => { // Automatic pending, error, and optimistic UI handling await searchAPI(query); });
New use
Hook
useReads resources (Promises, Context) in render:
import { use } from "react"; // Read promises in Server Components const data = use(fetchPromise); // Read context const theme = use(ThemeContext);
Use case: Streaming data in Server Components without useEffect.
Server Components (Stable)
Production-ready and used at scale by Meta (Facebook, Instagram):
// Server Component - runs on server only async function BlogPost({ id }) { const post = await db.post.findUnique({ where: { id } }); return <article>{post.content}</article>; }
Key characteristics:
- Zero JavaScript bundled to client
- Direct database access
- Build-time or per-request rendering
- Next.js defaults to Server Components
React Compiler (Stable Integration with Next.js 16)
Automatically optimizes components without manual memoization:
Before:
const memoizedValue = useMemo(() => expensiveCalc(a, b), [a, b]); const memoizedCallback = useCallback(() => doSomething(a, b), [a, b]);
With Compiler:
// Compiler automatically optimizes const value = expensiveCalc(a, b); const callback = () => doSomething(a, b);
Capabilities:
- Eliminates need for useMemo/useCallback in most cases
- Automatic re-render optimization
- Integrated and stable in Next.js 16
Server Functions (formerly Server Actions)
Simplified server-side mutations:
// app/actions.ts "use server"; export async function updateProfile(formData: FormData) { const name = formData.get("name"); await db.user.update({ where: { id }, data: { name } }); } // Client Component usage import { updateProfile } from "./actions"; export default function ProfileForm() { return ( <form action={updateProfile}> <input name="name" /> <button type="submit">Update</button> </form> ); }
Simplified Forms
React 19 eliminates much of the complexity:
// No more controlled state needed export default function ContactForm() { return ( <form action={async (formData) => { await submitToServer(formData); }} > <input name="email" /> <button type="submit">Submit</button> </form> ); }
API Simplifications
Context Providers - No More .Provider
.Provider// Before <MyContext.Provider value={value}>{children}</MyContext.Provider> // React 19+ <MyContext value={value}>{children}</MyContext>
Ref as Prop - No More forwardRef
forwardRef// Before const Button = forwardRef((props, ref) => <button ref={ref} {...props} />); // React 19+ const Button = ({ ref, ...props }) => <button ref={ref} {...props} />;
Document Metadata Support
Place
<title>, <meta>, <link> directly in components:
function BlogPost({ title, description }) { return ( <> <title>{title} | My Blog</title> <meta name="description" content={description} /> <meta property="og:title" content={title} /> <article>{content}</article> </> ); }
React automatically "hoists" these to
<head>.
Enhanced Ref Callbacks
Ref callbacks can now return cleanup functions:
const buttonRef = useCallback((element: HTMLButtonElement | null) => { if (!element) return; // cleanup on unmount const handler = () => console.log("Clicked"); element.addEventListener("click", handler); return () => element.removeEventListener("click", handler); }, []);
Improved Hydration
- Better handling of third-party script DOM mutations
- Enhanced error messages with detailed diffs
- Consolidated error logging
New Error Callbacks
createRoot(document.getElementById("root")!, { onCaughtError: (error, errorInfo) => { // Errors caught by Error Boundaries console.error("Caught:", error, errorInfo); }, onUncaughtError: (error, errorInfo) => { // Errors NOT caught by Error Boundaries console.error("Uncaught:", error, errorInfo); }, });
Custom Elements Support
Full support for Web Components with proper attribute and event handling.
Next.js 16 (Released October 2025)
Major Changes
Turbopack - Now Default & Stable
Turbopack is now the default bundler for both
next dev and next build:
# Turbopack is now default - no flags needed next dev next build
Performance improvements:
- 5-10x faster Fast Refresh
- Significantly faster builds
- Production-ready stability
Cache Components (New Programming Model)
Cache Components replace Partial Prerendering (PPR) with a more explicit caching model:
// next.config.js - Enable Cache Components export default { cacheComponents: true, // Opt-in feature };
Key characteristics:
- More explicit and flexible than implicit App Router caching
- Requires opt-in via config flag
- Component-level caching control
- Supersedes experimental PPR from Next.js 15
proxy.ts
Replaces middleware.ts
proxy.tsmiddleware.tsMiddleware has been renamed to proxy:
// Before: middleware.ts export function middleware(request: NextRequest) { // logic } // After: proxy.ts export function proxy(request: NextRequest) { // Same logic, just renamed }
Migration:
# Automated codemod available npx @next/codemod@canary middleware-to-proxy
What changed:
- File renamed:
→middleware.tsproxy.ts - Export renamed:
→middlewareproxy - Logic remains identical
- Runs on Node.js runtime
Async Route Parameters (Breaking Change)
Route parameters are now async:
// Before Next.js 16 export default async function Page({ params, searchParams }) { const id = params.id; const query = searchParams.q; } // Next.js 16+ export default async function Page({ params, searchParams }) { const id = await params.id; // Now async! const query = await searchParams.q; // Now async! }
This is a breaking change requiring migration of components using params/searchParams.
React 19.2 Integration
Full compatibility and optimization for React 19.2 features.
Deprecated APIs Removed
- Various
APIs promoted to stableunstable_ - Old middleware convention fully removed
- Legacy caching patterns removed
Next.js 15 Features (Still Relevant)
App Router (Default)
File-system based router with Server Components:
app/ layout.tsx # Root layout page.tsx # Home page blog/ layout.tsx # Blog section layout [slug]/ # Dynamic route page.tsx # Blog post page
Server Actions (Stable)
Direct server-side mutations from client components:
// app/actions.ts "use server"; export async function createTodo(formData: FormData) { const title = formData.get("title"); await db.todo.create({ data: { title } }); } // app/page.tsx import { createTodo } from "./actions"; export default function Page() { return ( <form action={createTodo}> <input name="title" /> <button type="submit">Add</button> </form> ); }
Server Components (Default)
All components in
app/ are Server Components by default:
// Server Component - no 'use client' needed async function Dashboard() { const user = await getCurrentUser(); const posts = await db.post.findMany(); return <div>Welcome {user.name}</div>; }
Add
'use client' directive only for:
- Event handlers (
, etc.)onClick - React hooks (
,useState
, etc.)useEffect - Browser APIs
Improved Caching
More predictable and granular caching:
- Better defaults for data fetching
- Explicit cache control via
/revalidatePathrevalidateTag
requests cached by defaultfetch
// Cache for 1 hour const data = await fetch("https://api.example.com/data", { next: { revalidate: 3600 }, }); // Invalidate on demand revalidatePath("/blog"); revalidateTag("posts");
after()
API
after()Post-response operations:
import { after } from "next/server"; export default function handler() { after(() => { // Runs after response is sent to client analytics.track(); }); return <Response />; }
Best Practices (2025-2026)
Server-First Mental Model
- Default to Server Components - Only use Client Components for interactivity
- Leverage Server Functions - Replace API routes for mutations
- Stream with Suspense - Progressive loading for better UX
- Push state to edges - Client components only where necessary
Form Handling Pattern
// Server Action "use server"; async function submitContact(prevState, formData) { const email = formData.get("email"); await db.contact.create({ data: { email } }); return { success: true }; } // Client Component ("use client"); import { useActionState } from "react"; import { submitContact } from "./actions"; export default function ContactForm() { const [state, formAction, isPending] = useActionState(submitForm, null); return ( <form action={formAction}> <input name="email" disabled={isPending} /> <button disabled={isPending}> {isPending ? "Sending..." : "Submit"} </button> {state?.success && <p>Thanks!</p>} </form> ); }
Optimistic UI Pattern
"use client"; import { useOptimistic } from "react"; import { toggleLike } from "./actions"; function LikeButton({ postId, initialLiked }) { const [optimisticLiked, addOptimistic] = useOptimistic( initialLiked, (state) => !state ); return ( <button formAction={async () => { addOptimistic(); await toggleLike(postId); }} > {optimisticLiked ? "Unlike" : "Like"} </button> ); }
Server Component Data Fetching
// Simple, direct database access async function BlogList() { const posts = await db.post.findMany({ orderBy: { createdAt: "desc" }, }); return ( <div> {posts.map((post) => ( <article key={post.id}> <h2>{post.title}</h2> <p>{post.excerpt}</p> </article> ))} </div> ); }
Streaming with Suspense
import { Suspense } from "react"; export default function Dashboard() { return ( <div> <h1>Dashboard</h1> <Suspense fallback={<StatsSkeleton />}> <Stats /> </Suspense> <Suspense fallback={<PostsSkeleton />}> <RecentPosts /> </Suspense> </div> ); }
Migration Guides
Next.js 15 → 16
-
Update async params:
// Add await to all params/searchParams access const id = await params.id; -
Rename middleware to proxy:
npx @next/codemod@canary middleware-to-proxy -
Enable Turbopack (already default, but verify):
next dev --turbo # Should be default now -
Consider Cache Components:
// next.config.js export default { cacheComponents: true, // Opt-in for new caching model };
React 18 → 19
- Update forms to use Actions
- Simplify components - Remove
, update Context syntaxforwardRef - Remove manual memoization where React Compiler is active
- Add error callbacks to
createRoot - Migrate to native metadata instead of third-party libraries
Pages Router → App Router
| Pages Router | App Router |
|---|---|
| |
| async Server Component |
| async Server Component + |
| |
| |
| |
API routes | Route handlers |
Common Patterns
Document Metadata by Route
// app/blog/[slug]/page.tsx export async function generateMetadata({ params }) { const post = await getPost(params.slug); return { title: post.title, description: post.excerpt, openGraph: { title: post.title, images: [post.ogImage], }, }; }
Loading States
// app/blog/loading.tsx export default function Loading() { return <BlogListSkeleton />; } // Or inline Suspense export default function BlogPage() { return ( <Suspense fallback={<BlogListSkeleton />}> <BlogList /> </Suspense> ); }
Error Handling
// app/blog/error.tsx "use client"; export default function Error({ error, reset }) { return ( <div> <h2>Something went wrong!</h2> <button onClick={() => reset()}>Try again</button> </div> ); }
Resources
Official Documentation
- React 19 Official Blog
- React 19.2 Release
- React Versions
- Next.js 16 Official Blog
- Next.js 16 Upgrade Guide
- Cache Components Documentation
- Proxy Migration Guide
React References
- useActionState Reference
- useOptimistic Reference
- useFormStatus Reference
- use Reference
- Server Components Reference
- Server Functions Reference