cursor-rules-pack
7 production-tested Cursor Rules — dependency discipline, error handling, state management, webhook security, and more. Free sample from the full 50-rule pack.
State management and data patterns — parallel fetching, optimistic updates, cache invalidation.
State management and data patterns — parallel fetching, optimistic updates, cache invalidation.
## Parallel Data Fetching Pattern
```typescript
// ✅ Parallel — ~90ms total
const [user, posts, analytics] = await Promise.all([
getUser(userId),
getPosts(userId),
getAnalytics(userId),
])
// ❌ Sequential — ~230ms total
const user = await getUser(userId)
const posts = await getPosts(userId)
const analytics = await getAnalytics(userId)
```
## Error Result Pattern
Return typed errors instead of throwing everywhere:
```typescript
type Result<T> = { ok: true; data: T } | { ok: false; error: string }
```Core production rules — dependency discipline, error handling, comments, naming. Apply to all TypeScript/JavaScript projects.
Core production rules — dependency discipline, error handling, comments, naming. Apply to all TypeScript/JavaScript projects.
## Dependency Discipline
Before suggesting a new npm package: (1) state what it does in one sentence, (2) confirm it's actively maintained (last publish < 6 months), (3) check if < 30 lines replaces it. Never add a dependency for a task under 20 lines of code.
## Explicit Error Handling
Always wrap async operations in try/catch. Never swallow errors silently. Log with context: `logger.error('[FunctionName] description', { error, context })`. Always provide user-facing error states in UI components.
## Comments Policy
Write self-documenting code first. Comments only for: (1) non-obvious business logic — explain WHY not WHAT, (2) workarounds — explain why and link the issue, (3) complex algorithms. Never comment what the code clearly does.
## Naming Conventions
PascalCase for components/types, camelCase for functions/variables, SCREAMING_SNAKE_CASE for constants, kebab-case for file names. Booleans start with `is`, `has`, `can`, or `should`. Descriptive names: `getUserByEmail` not `getUser`.
## File Size Discipline
Keep files under 200 lines. If a file grows beyond that, proactively suggest how to split it. Co-locate related files: keep a component's types, hooks, and utilities in the same folder.Database and backend rules — always use select, API route security checklist, webhook idempotency, Prisma best practices.
Database and backend rules — always use select, API route security checklist, webhook idempotency, Prisma best practices.
## Database Query Safety
Never return full database records to the client — always use `select` to specify exactly which fields are needed. This prevents exposing password hashes, reset tokens, and sensitive fields. Paginate queries that could return more than 50 rows.
## API Route Security Checklist
Every route must: (1) authenticate first — return 401 if no session, (2) validate body with Zod — return 400 with field errors if invalid, (3) authorize the action — return 403 if user can't do this, (4) return typed responses `{ data }` on success / `{ error }` on failure, (5) correct HTTP status codes — never return 200 for errors.
## Webhook Security
Verify the signature in the first 3 lines — reject immediately if invalid. Respond with HTTP 200 within 5 seconds — offload processing to a background job. Implement idempotency using the event ID (upsert, not create).
## Prisma Best Practices
Use `db.$transaction()` for operations writing to multiple tables. Every model needs: `id` (cuid default), `createdAt`, `updatedAt`. Add `@@index` for every foreign key and every field used in WHERE clauses.Next.js App Router rules — server components first, state management hierarchy, parallel data fetching, loading/error states.
Next.js App Router rules — server components first, state management hierarchy, parallel data fetching, loading/error states.
## Server Components First
Default to server components. Add "use client" only when required by: event handlers, useState, useEffect, browser-only APIs. Always explain your choice when adding "use client". Use Server Actions for mutations.
## State Management Hierarchy
Follow this order strictly:
- URL state → filters, pagination, search (useSearchParams)
- React state → UI-only, ephemeral (useState)
- Zustand → cross-component app state
- React Query → all server state
Never use Zustand to cache server data. Never reach for Redux.
## Parallel Data Fetching
Identify and parallelize independent fetches — use Promise.all instead of sequential awaits. When making a sequential await, add a comment explaining the dependency that forces it.
## Loading & Error States
Every async operation needs three states: loading, error, success. Use skeleton components (not spinners) for content loading. Error boundaries must show actionable messages.