Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ By adding selected `.mdc` files to `.cursor/rules/`, you can use these rules dir
- [Next.js (TypeScript App)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-typescript-app-cursorrules-prompt-file.mdc) - Next.js development with TypeScript integration.
- [Next.js (TypeScript)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-typescript-cursorrules-prompt-file.mdc) - Next.js development with TypeScript integration.
- [Next.js (TypeScript, Tailwind)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-typescript-tailwind-cursorrules-prompt-file.mdc) - Next.js development with TypeScript and Tailwind CSS integration.
- [Next.js + TypeScript (Annotated + Enforced)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-typescript-annotated-enforced-cursorrules-prompt-file.mdc) - Next.js + TypeScript rules where every rule states *why* it exists, paired with Claude Code enforcement hooks (Prettier/ESLint on edit, `tsc --noEmit` on stop) so the rules run, not just suggest.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
- [Next.js (Vercel, Supabase)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-vercel-supabase-cursorrules-prompt-file.mdc) - Next.js development with Vercel and Supabase integration.
- [Next.js (Vercel, TypeScript)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-vercel-typescript-cursorrules-prompt-file.mdc) - Next.js development with Vercel and TypeScript integration.
- [Next.js (App Router)](https://github.com/PatrickJS/awesome-cursorrules/blob/main/rules/nextjs-app-router-cursorrules-prompt-file.mdc) - Next.js development with App Router integration.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
---
description: "Next.js (App Router) + React 19 + TypeScript rules where every rule states WHY it exists, paired with Claude Code enforcement hooks that format/lint/type-check automatically."
globs: **/*.{ts,tsx}
alwaysApply: false
---
// Next.js + TypeScript .cursorrules — annotated + enforced
// Each rule carries the reason it exists (models follow rules they understand).
// Pairs with a synced Claude Code CLAUDE.md + .claude/settings.json hooks that run
// Prettier/ESLint on edit and `tsc --noEmit` on session stop — so the rules RUN, not just suggest.
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
// Source / full multi-stack pack (Node/Express, FastAPI, Go): https://github.com/iPythoning/claude-cursor-config-nextjs

You are working in a Next.js (App Router) + React 19 + TypeScript (strict) project. npm is the package manager.

## Scope discipline
- Change only what the task requires. Do NOT refactor, rename, or reformat unrelated code. Why: unrequested edits bury the real diff and break unrelated work.
- Do NOT add a new dependency, pattern, or abstraction without asking. Prefer what the codebase already uses. Why: a second state library or HTTP client is a tax forever.
- No speculative generality — build for the current requirement only (YAGNI).

## TypeScript
- strict mode. NEVER use `any` — use `unknown` and narrow. Why: `any` silently disables the type system exactly where bugs hide; `unknown` forces a deliberate check.
- Prefer `type` for unions/objects; `interface` only for declaration merging.
- PascalCase type names, no `I` prefix.
- Derive types from one source of truth (z.infer, ReturnType, `as const`) — never maintain parallel shapes by hand.

## React / Next.js
- Server Components by default. Add "use client" ONLY for state, effects, or browser APIs. Why: shipping client JS you don't need is the most common Next.js performance regression.
- Fetch data in Server Components or route handlers, NOT in useEffect. Why: useEffect fetching causes request waterfalls and loading-flash; server fetching is parallel and cache-aware.
- PascalCase components, useCamelCase hooks, one component per file.
- Co-locate by feature, not by file type. Why: feature folders keep related code together and make deletion safe.
- Keep server-only secrets out of any module a Client Component imports (use `server-only`).

## State
- Server data: RSC or TanStack Query. Shared client state: a small store, only when prop-passing hurts. URL state: search params. Forms: React Hook Form + schema validation.
- NEVER copy server data into a client store. Why: two sources of truth drift; derive instead of duplicate.

## Error handling
- Handle errors explicitly at every boundary. NEVER swallow them with empty catch blocks. Why: a silent `catch {}` turns a clear failure into a mystery bug three screens away.
- Validate all external input (form data, params, API responses) with a schema at the edge. Why: trusting unvalidated external data is the root of most runtime crashes and injection bugs.
- User surfaces show friendly messages; the server logs full context.

## Code style
- Immutable by default — return new objects, don't mutate inputs. Why: hidden mutation is the hardest class of bug to trace.
- Early returns over deep nesting (max ~3 levels). Named constants over magic numbers.
- Functions < ~50 lines, files < ~400 (hard cap 800). Why: small units are reviewable, testable, and reusable.
- No console.log, commented-out code, or context-free TODOs in committed code.

## Security
- No hardcoded secrets (env vars; validate at startup). No unsanitized HTML / raw dangerouslySetInnerHTML.
- Parameterize every DB query. CSRF + rate limiting on state-changing routes.

## Testing & done
- New logic ships with AAA tests covering edge cases. Descriptive test names.
- Before declaring done: `npm run build`, `npm run lint`, and tests must pass. No `any`, no swallowed errors, no hardcoded secrets, no stray console.log. Diff contains only the required change. Why: "it compiles in my head" is not verification.
Loading