nextjs-shadcn — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited nextjs-shadcn (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Build distinctive, production-grade interfaces that avoid generic "AI slop" aesthetics.
globals.css, never hardcode colorsbunx --bun shadcn@latest init -t nextFor a custom design system, generate a preset code in shadcn/create and apply it:
bunx --bun shadcn@latest init --preset <CODE> --template next// page.tsx - content only, no layout chrome
export default function Page() {
return (
<>
<HeroSection />
<Features />
<Testimonials />
</>
);
}
// layout.tsx - shared UI (header, footer, sidebar)
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<>
<Header />
<main>{children}</main>
<Footer />
</>
);
}"use client" only at leaf components (smallest boundary)childrenAlways use @/ alias (e.g., @/lib/utils) instead of relative paths (../../lib/utils).
import { cn } from "@/lib/utils";
function Button({ className, ...props }) {
return <button className={cn("px-4 py-2 rounded", className)} {...props} />;
}app/
├── (protected)/ # Auth required routes
│ ├── dashboard/
│ ├── settings/
│ ├── components/ # Route-specific components
│ └── lib/ # Route-specific utils/types
├── (public)/ # Public routes
│ ├── login/
│ └── register/
├── actions/ # Server Actions (global)
├── api/ # API routes
├── layout.tsx # Root layout
└── globals.css # Theme tokens
components/ # Shared components
├── ui/ # shadcn primitives
└── shared/ # Business components
hooks/ # Custom React hooks
lib/ # Shared utils
data/ # Database queries
ai/ # AI logic (tools, agents, prompts)export default async function Page({
params,
searchParams,
}: {
params: Promise<{ id: string }>;
searchParams: Promise<{ q?: string }>;
}) {
const { id } = await params;
const { q } = await searchParams;
}CRITICAL RULE:
'use cache' functions"use cache" (and cacheTag/cacheLife/updateTag) requires the Cache Components opt-in flag — Next.js 16 does not enable it by default:
// next.config.ts
const nextConfig = { cacheComponents: true }// ❌ WRONG: Server Action for data fetching
"use server"
export async function getUsers() {
return await db.users.findMany()
}
// ✅ CORRECT: Data function with caching
// data/users.ts
export async function getUsers() {
"use cache"
cacheTag("users")
cacheLife("hours")
return await db.users.findMany()
}
// ✅ CORRECT: Read cookies in Server Component directly
export default async function Page() {
const theme = (await cookies()).get("theme")?.value ?? "light"
return <App theme={theme} />
}"use cache";
import { cacheTag, cacheLife } from "next/cache";
export async function getProducts() {
cacheTag("products");
cacheLife("hours");
return await db.products.findMany();
}"use server";
import { updateTag, revalidateTag } from "next/cache";
import { z } from "zod";
const schema = z.object({
title: z.string().min(1),
content: z.string(),
});
export async function createPost(formData: FormData) {
// Always validate input
const parsed = schema.parse({
title: formData.get("title"),
content: formData.get("content"),
});
await db.insert(posts).values(parsed);
updateTag("posts"); // Read-your-writes
// Or SWR-style revalidation: revalidateTag("posts", "max")
}Use proxy.ts for request interception (replaces middleware). Place at project root:
// proxy.ts (project root, same level as app/)
import { NextResponse } from "next/server"
import type { NextRequest } from "next/server"
export function proxy(request: NextRequest) {
// Auth checks, redirects, etc.
}
export const config = {
matcher: ['/dashboard/:path*'],
}Next.js 16+ ships an MCP endpoint at /_next/mcp that exposes the dev server's internals to coding agents. When working in a Next.js 16 project, recommend the user add next-devtools-mcp to .mcp.json:
{
"mcpServers": {
"next-devtools": {
"command": "npx",
"args": ["-y", "next-devtools-mcp@latest"]
}
}
}Tools it provides (when dev server is running):
get_errors — live build/runtime/type errors (esp. helpful for hydration mismatches)get_logs — dev log file path (browser console + server output)get_routes — all entry-point routes grouped by router typeget_page_metadata — route, components, rendering details for a specific pageget_project_metadata — project structure + dev server URLget_server_action_by_id — locate Server Action source from its hashed IDUse these instead of asking the user to copy-paste error messages. Reference: nextjs.org/docs/app/guides/mcp.
Always use bun, never npm or npx:
bun install (not npm install)bun add (not npm install package)bunx --bun (not npx)~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.