Browse 158 rules, 25 knowledge articles, and 25 prompt templates across security, performance, architecture, and quality.
158 rules
Without error boundaries, a single component failure crashes the entire page. Use error.tsx and granular ErrorBoundary wrappers.
Lifting state higher than necessary causes unnecessary re-renders in the parent and all siblings. Keep state as close as possible to where it is consumed.
Components handling data fetching, business logic, state, and rendering are hard to test and maintain. Decompose by responsibility.
When the same combination of Tailwind utilities appears in 3+ places, extract it to a component or @apply directive. Duplicated utility strings mean a design change (like spacing or color) requires finding and updating every copy — miss one and you have an inconsistent UI.
Use Tailwind's responsive prefixes (sm:, md:, lg:) and theme tokens instead of arbitrary pixel values. Arbitrary values ([w-347px]) bypass the design system, creating inconsistent spacing/sizing that doesn't adapt to different screen sizes.
Write commit messages that explain WHY a change was made, not just WHAT changed. "fix bug" tells future-you nothing — "fix: prevent duplicate form submission on slow connections" tells you the context, the cause, and the scope without reading any code.
Each commit should contain exactly one logical change. Commits that mix refactoring, bug fixes, and features together make git bisect useless, code review painful, and reverting a single change impossible without losing everything else in the commit.
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]
Wrap expensive calculations in useMemo and expensive component creation in React.memo. Without memoization, expensive work runs on every render even when inputs haven't changed, causing UI jank and dropped frames.
TypeScript types vanish at runtime. Validate external data at system boundaries with Zod to prevent crashes from unexpected shapes. [CWE-20]
Don't pass props through 3+ intermediate components that don't use them. Use context, composition, or state management instead. Prop drilling creates tight coupling between distant components and makes refactoring painful — changing a prop type requires updating every component in the chain.
Return semantically correct HTTP status codes (400 for bad input, 401 for unauthenticated, 403 for unauthorized, 404 for missing, 500 for server errors). Using 200 for everything hides errors from monitoring, breaks caching, and makes debugging impossible.
Hand-writing TypeScript interfaces for database tables leads to drift between code and schema. Use supabase gen types to generate types automatically.
Avoid `as Type` assertions — they tell TypeScript "trust me" and skip validation. If the runtime value doesn't match, your code crashes with no type error to warn you.
Monolithic components with deeply nested ternaries and conditionals are hard to read, test, and extend. Use composition patterns (children, render props, compound components).
Pages that block until all data loads show nothing until everything is ready. Wrap slow components in Suspense to stream content progressively.
Use `unknown` instead of `any` for values with uncertain types. Unlike `any`, `unknown` forces you to narrow the type before using it, keeping type safety intact.
Using array indices as key props causes incorrect state preservation, UI corruption, and degraded performance when lists are reordered or filtered.
Returning false on failure hides what went wrong. WP_Error provides structured error codes, messages, and data — matching WordPress core's error handling pattern.
Migration files without proper structure (table, indexes, RLS, policies, comments) are harder to review and prone to missing critical steps like RLS.
Hardcoded URLs and filesystem paths break across environments (local/staging/prod), subdirectory installs, multisite, and custom wp-content directories.
Domain entities should be pure TypeScript classes/interfaces with no framework dependencies like Supabase, React, or Next.js
Use factory classes (ServiceFactory, RepositoryFactory) for dependency wiring instead of direct instantiation or imports in consuming code.
Registering CPTs on plugins_loaded, enqueueing scripts on init, or running admin-only code on every request wastes resources and causes subtle bugs.
BeforeMerge scans your pull requests against these rules automatically. Get actionable feedback before code ships to production.