Comprehensive Next.js v16 development with Cache Components, feature-based architecture, and best practices. Use for ANY Next.js 16 task to know - (1) Project structure with features folder pattern, (2) Where to fetch data with use cache, (3) Server vs Client component decisions, (4) One file per query/type/schema/hook pattern, (5) Cache invalidation with updateTag/revalidateTag, (6) Proper component organization within features. Apply to all Next.js 16 development tasks.
/plugin marketplace add horuz-ai/claude-plugins/plugin install nextjs@horuzThis skill inherits all available tools. When active, it can use any tool Claude has access to.
references/checklists.mdreferences/components.mdreferences/data-layer.mdreferences/feature-structure.mdreferences/i18n.mdreferences/pages-layouts.mdreferences/server-actions.mdreferences/shared-feature.mdArchitecture patterns for Next.js 16 with Cache Components and feature-based organization.
"use cache" explicitlyfeatures/{feature}/
├── components/
│ ├── server/ # Async data-fetching components
│ ├── client/ # 'use client' interactive components
│ └── skeletons/ # Loading states for Suspense
├── data/ # Database queries (SELECT, INSERT, UPDATE, DELETE)
├── actions/ # Server Actions ('use server' + cache invalidation)
├── types/ # TypeScript types (1 file = 1 type)
├── schemas/ # Zod schemas (1 file = 1 schema)
├── hooks/ # Client-side hooks
└── lib/ # Feature-specific utilities
| Type | Pattern | Example |
|---|---|---|
| Server component | kebab-case.tsx | agent-header.tsx |
| Client component | kebab-case.tsx | login-form.tsx |
| Skeleton | {name}-skeleton.tsx | agent-header-skeleton.tsx |
| GET query | get-{entity}.ts | get-agent.ts |
| GET multiple | get-{entities}.ts | get-agents.ts |
| CREATE | create-{entity}.ts | create-agent.ts |
| DELETE | delete-{entity}.ts | delete-agent.ts |
| Server Action | {verb}-{entity}-action.ts | delete-agent-action.ts |
// Data file (SELECT with cache)
export async function getEntity(id: number) {
"use cache";
cacheTag(`entity-${id}`);
cacheLife("hours");
return await db.select()...
}
// Server Action (mutation + invalidation)
"use server";
export async function deleteEntityAction(id: number) {
await deleteEntity(id);
updateTag(`entity-${id}`);
}
@/features/...../../../app/ → features/ → shared/Load these based on what you need: