BeforeMerge

AI-native code review knowledge base. Structured rules that catch what linters miss.

Product

  • Features
  • Explore
  • Pricing
  • Docs
  • GitHub

Company

  • About
  • Blog
  • Contributors
  • Contributing

Legal

  • Privacy Policy
  • Terms of Service
  • MIT License

© 2026 BeforeMerge. Built by Peter Krzyzek

BeforeMerge
Features
Explore
PricingBlogContributorsInstall Guide
3Sign In
FeaturesExplore
RulesSkillsKnowledgePrompts
PricingBlogContributorsInstall Guide
Sign In

Explore

Browse 354 rules, 42 knowledge articles, and 28 prompt templates across security, performance, architecture, and quality.

Sort:
Previous1...1415Next

Automate these checks on every PR

BeforeMerge scans your pull requests against these rules automatically. Get actionable feedback before code ships to production.

Join WaitlistLearn More

354 rules

Avoid Prop Drilling

MEDIUM

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.

ArchitectureState ManagementReactReact

Use Stable Keys for List Items

HIGH

Always use stable, unique keys in array .map() renders. Missing or unstable keys (like array index) cause React to destroy and recreate DOM nodes, losing component state and causing visual glitches.

QualityReactquality

Avoid useEffect for Derived State

HIGH

Don't use useEffect to sync state that can be computed from existing state or props. Derived values should be calculated during render, not in effects. Effects for derived state cause extra renders, race conditions, and stale UI that flash incorrect data before correcting.

QualityState ManagementReact

Avoid the any Type

HIGH

Never use `any` as a type annotation. `any` disables all type checking for that value and everything it touches, spreading through your codebase like a virus — one `any` can silently disable type safety across dozens of files.

QualityqualityTypeScript

Avoid Inline Function Definitions in JSX

LOW

Extract event handlers defined inline in JSX to named functions or useCallback. Inline functions create new references every render, breaking React.memo and causing unnecessary child re-renders.

PerformanceReactJSX

Memoize Expensive Computations

MEDIUM

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.

PerformanceReactperformance

Version Your API

MEDIUM

Version your API from day one (URL prefix, header, or query param). Without versioning, any breaking change forces all clients to update simultaneously or breaks them without warning.

ArchitectureREST

Add Indexes for Frequent Queries

HIGH

Add database indexes for columns used in WHERE, JOIN, and ORDER BY clauses. Without indexes, the database scans every row in the table for every query — a table with 1M rows takes seconds instead of milliseconds.

PerformanceDatabaseSQL

Avoid SELECT * in Production

MEDIUM

Never use SELECT * in production code. SELECT * fetches every column including large text/blob fields you don't need, wastes bandwidth, breaks when columns are added, and prevents the database from using covering indexes.

PerformanceQueriesDatabase

Use Parameterized Queries

CRITICAL

Always use parameterized queries or prepared statements, never string concatenation. String-interpolated SQL is the #1 cause of SQL injection — an attacker can modify your query to read, modify, or delete your entire database.

SecurityDatabaseSQL

Normalize Data Appropriately

MEDIUM

Normalize your database schema to at least 3NF to eliminate data duplication. Denormalized data means the same fact is stored in multiple places — when you update one copy, the others become stale, creating data inconsistencies that are nearly impossible to track down.

ArchitectureNormalization

Add Foreign Key Constraints

HIGH

Define foreign key constraints for all table relationships. Without foreign keys, the database allows orphaned rows (e.g., an order referencing a deleted customer), corrupting data integrity silently.

QualityqualityDatabase

Enable RLS on Every Table

CRITICAL

Every table in the public schema must have Row Level Security enabled with at least one policy per operation. Without RLS, the Supabase API exposes every row to every request — any browser with your anon key or any logged-in user can read, modify, or delete data belonging to other users. A single table missing RLS can leak your entire user base's private data or let one user overwrite another's records.

Securityrlssecurity

Extract Duplicated Logic After Third Occurrence

HIGH

When the same logic appears in three or more places, extract it into a shared function, hook, or module. Duplicated code means that when you fix a bug or change behavior in one copy, the other copies silently remain broken — leading to inconsistent behavior, hard-to-trace bugs, and wasted time tracking down "why does it work here but not there."

Qualityquality

Authenticate Server Actions Like API Routes

CRITICAL

Every Server Action must verify authentication as its first operation. Server Actions compile to public HTTP POST endpoints — anyone on the internet can call them directly with a simple fetch request, bypassing your UI entirely. Even if you have middleware or layout-level auth checks, the action itself must independently verify the user because external guards can be misconfigured, incomplete, or bypassed. Without per-action auth, an attacker can invoke privileged operations like deleting data, changing settings, or accessing resources they should never reach.

Securitynextjs

Prefer Server Components Over Client Components

HIGH

Only add "use client" when a component needs hooks, event handlers, or browser APIs. Every unnecessary "use client" directive ships the component and all its dependencies to the browser as additional JavaScript — slowing down page loads, increasing bandwidth costs, and degrading the experience for users on slow connections or low-powered devices.

Performancebundle-sizeperformance

Use getUser() Instead of getSession()

CRITICAL

Always use supabase.auth.getUser() on the server side to verify identity. getSession() reads the JWT from cookies and decodes it without verifying the signature against the auth server — so if an attacker tampers with the token (changing the user ID, role, or email), your server-side code will trust the forged claims as legitimate. This is a complete authentication bypass: the attacker can impersonate any user, escalate privileges, or access data they were never authorized to see.

Securitysupabaseauthentication

Dependency Direction Violation

CRITICAL

Dependencies must flow inward: Presentation -> Controller -> Service -> Repository -> Domain. Never import upward across layers. [CWE-1047]

Architecturesolid
React
React
TypeScript
React
React
architecture
API Design
SQL & Databases
SQL & Databases
SQL & Databases
Database
SQL & Databases
SQL & Databases
Supabase
refactoring
Architecture
server-actions
Next.js
Next.js
Supabase
architecture
Architecture