Browse 158 rules, 25 knowledge articles, and 25 prompt templates across security, performance, architecture, and quality.
158 rules
TypeScript types vanish at runtime. Validate external data at system boundaries with Zod to prevent crashes from unexpected shapes. [CWE-20]
Using 'any' or 'as any' at API boundaries, form handlers, and external data silently disables TypeScript safety, causing runtime crashes from unexpected data. [CWE-20]
Casting API responses, form data, or URL params with 'as Type' bypasses TypeScript guarantees. When the shape doesn't match, crashes happen far from the boundary. [CWE-20]
Hardcoded secrets persist in Git history forever. Use environment variables and never prefix secrets with NEXT_PUBLIC_. [CWE-798 · A07:2021]
useEffect hooks that set up subscriptions, timers, or event listeners without cleanup cause memory leaks, stale state updates, and race conditions.
Inline objects, arrays, and functions as props create new references every render, defeating React.memo and causing cascading re-renders across the tree.
Event handlers and effects that capture state in closures can reference outdated values, causing silent data corruption and missed updates.
Adding 'use client' unnecessarily ships component JS to the browser. Only use it when you need hooks, event handlers, or browser APIs.
Sequential await calls on independent operations create request waterfalls. Use Promise.all or Suspense boundaries to parallelize.
Fetching related data inside loops creates N+1 queries that scale linearly with data size. Use eager loading or batch queries instead. [CWE-400]
Using array indices as key props causes incorrect state preservation, UI corruption, and degraded performance when lists are reordered or filtered.
Raw <img> tags skip automatic optimization, lazy loading, and responsive sizing. next/image provides WebP/AVIF conversion, blur placeholders, and CLS prevention.
External font loading from Google Fonts or CDNs causes layout shift and render-blocking requests. next/font self-hosts fonts with zero layout shift.
Large client libraries loaded synchronously block the initial page load. Use next/dynamic or React.lazy to code-split and load them on demand.
Barrel file imports in Client Components force bundlers to load entire libraries. Use direct imports or Next.js optimizePackageImports.
Missing loading.tsx causes full-page spinners instead of granular streaming. Missing error.tsx lets errors crash parent layouts instead of being contained.
Components handling data fetching, business logic, state, and rendering are hard to test and maintain. Decompose by responsibility.
Without error boundaries, a single component failure crashes the entire page. Use error.tsx and granular ErrorBoundary wrappers.
API routes with business logic are hard to test, audit, and secure. Keep route handlers under 100 lines by delegating to service classes. [CWE-1064]
API routes without rate limiting enable brute force, DDoS, and credit exhaustion attacks. Apply tiered rate limits as the first middleware. [CWE-770 · A04:2021]
Returning raw error messages or stack traces leaks implementation details. Return generic messages with a requestId for server-side debugging. [CWE-209]
State-changing API routes without CSRF validation allow cross-site request forgery. Validate tokens on POST/PUT/PATCH/DELETE with known exemptions. [CWE-352 · A01:2021]
Inconsistent error handling with thrown exceptions, returned nulls, and ad-hoc error objects makes callers fragile. Use a discriminated union ServiceResult type.
Creating new components or utilities without checking if one already exists leads to duplicated logic and inconsistency. Search existing code first.
BeforeMerge scans your pull requests against these rules automatically. Get actionable feedback before code ships to production.