

Also from Kynth Studios


Also from Kynth Studios


Also from Kynth Studios
123456# Creating Cursor Rules - Meta Rule78## Overview910This is a meta-rule for creating effective `.cursor/rules` files. Apply these principles when writing or improving Cursor IDE rules for your project.1112## When to Use1314**Use when:**15- Starting a new project and setting up `.cursor/rules`16- Improving existing project rules17- Converting skills or guidelines to Cursor format18- Team needs consistent coding standards1920**Don't use for:**21- Claude Code skills (those go in `.claude/skills/`)22- One-time instructions (just ask directly)23- User-specific preferences (those go in global settings)2425## Core Principles2627### 1. Be Specific and Actionable2829```markdown30# ❌ BAD - Vague31Write clean code with good practices.3233# ✅ GOOD - Specific34Use functional components with TypeScript.35Define prop types with interfaces, not inline types.36Extract hooks when logic exceeds 10 lines.37```3839### 2. Focus on Decisions, Not Basics4041```markdown42# ❌ BAD - Obvious43Use semicolons in JavaScript.44Indent with 2 spaces.4546# ✅ GOOD - Decision guidance47Choose Zustand for global state, React Context for component trees.48Use Zod for runtime validation at API boundaries only.49Prefer server components except for: forms, client-only APIs, animations.50```5152### 3. Organize by Concern5354```markdown55# ✅ GOOD Structure5657## Tech Stack58- Next.js 14 with App Router59- TypeScript strict mode60- Tailwind CSS for styling6162## Code Style63- Functional components only64- Named exports (no default exports)65- Co-locate tests with source files6667## Patterns68- Use React Server Components by default69- Client components: mark with "use client" directive70- Error handling: try/catch + toast notification7172## Project Conventions73- API routes in app/api/74- Components in components/ (flat structure)75- Types in types/ (shared), components/*/types.ts (local)76```7778## Rule Anatomy7980### MDC Format and Metadata8182Cursor rules are written in **MDC (.mdc)** format, which supports YAML frontmatter metadata and markdown content. The metadata controls how and when rules are applied.8384### Required YAML Frontmatter8586Every Cursor rule MUST start with YAML frontmatter between `---` markers:8788```yaml89---90description: Brief description of when and how to use this rule91globs: ["**/*.ts", "**/*.tsx"]92alwaysApply: false93---94```9596### Frontmatter Properties9798| Property | Type | Required | Description |99|----------|------|----------|-------------|100| `description` | string | **Yes** | Brief description of the rule's purpose. Used by AI to decide relevance. Never use placeholders like `---` or empty strings. |101| `globs` | array | No | File patterns that trigger auto-attachment (e.g., `["**/*.ts"]`). Leave empty or omit if not using Auto Attached type. |102| `alwaysApply` | boolean | No | If `true`, rule is always included in context. If `false` or omitted, behavior depends on Rule Type. |103104### Rule Types105106Control how rules are applied using the **type dropdown** in Cursor:107108| Rule Type | Description | When to Use |109|-----------|-------------|-------------|110| **Always** | Always included in model context | Core project conventions, tech stack, universal patterns that apply everywhere |111| **Auto Attached** | Included when files matching `globs` pattern are referenced | File-type specific rules (e.g., React components, API routes, test files) |112| **Agent Requested** | Available to AI, which decides whether to include it based on `description` | Contextual patterns, specialized workflows, optional conventions |113| **Manual** | Only included when explicitly mentioned using `@ruleName` | Rarely-used patterns, experimental conventions, legacy documentation |114115### Examples by Rule Type116117**Always Rule** (Core conventions):118```yaml119---120description: TypeScript and code style conventions for the entire project121alwaysApply: true122---123```124125**Auto Attached Rule** (File pattern-specific):126```yaml127---128description: React component patterns and conventions129globs: ["**/components/**/*.tsx", "**/app/**/*.tsx"]130alwaysApply: false131---132```133134**Agent Requested Rule** (Contextual):135```yaml136---137description: RPC service boilerplate and patterns for creating new RPC endpoints138globs: []139alwaysApply: false140---141```142143**Manual Rule** (Explicit invocation):144```yaml145---146description: Legacy API migration patterns (deprecated, use for reference only)147globs: []148alwaysApply: false149---150```151152### Best Practices for Frontmatter1531541. **Description is mandatory** - AI uses this to determine relevance. Be specific:155 - ❌ Bad: `Backend code`156 - ✅ Good: `Fastify API route patterns, error handling, and validation using Zod`1571582. **Use globs strategically** - Auto-attach to relevant file types:159 - React components: `["**/*.tsx", "**/*.jsx"]`160 - API routes: `["**/api/**/*.ts", "**/routes/**/*.ts"]`161 - Tests: `["**/*.test.ts", "**/*.spec.ts"]`1621633. **Avoid always applying everything** - Use `alwaysApply: true` sparingly:164 - ✅ Good for: Tech stack, core conventions, project structure165 - ❌ Bad for: Framework-specific patterns, specialized workflows1661674. **Make Agent Requested rules discoverable** - Write descriptions that help AI understand when to use:168 - Include keywords: "boilerplate", "template", "pattern for X"169 - Mention specific use cases: "when creating new API routes"170171### Additional Optional Fields172173While the core properties above control rule behavior, you may also include:174175**title:** (Optional)176- Clear, concise name for the rule177- Example: `Creating Cursor Rules`, `TypeScript Type Safety`178179**tags:** (Optional)180- Array of relevant tags for organization181- Use lowercase, kebab-case182- Example: `[meta, cursor, documentation, best-practices]`183184**source:** (Optional)185- Where the rule originated from186- Example: `claude-code-skill`, `custom`, `community`187188**IMPORTANT:** The `description` field is MANDATORY for all cursor rules. When converting skills to cursor rules or creating new rules, always include a valid description. Never use placeholders like `---` or empty strings.189190## Required Sections191192### Tech Stack Declaration193194```markdown195## Tech Stack196- Framework: Next.js 14197- Language: TypeScript 5.x (strict mode)198- Styling: Tailwind CSS 3.x199- State: Zustand200- Database: PostgreSQL + Prisma201- Testing: Vitest + Playwright202```203204**Why:** Prevents AI from suggesting wrong tools/patterns.205206### Code Style Guidelines207208```markdown209## Code Style210- **Components**: Functional with TypeScript211- **Props**: Interface definitions, destructure in params212- **Hooks**: Extract when logic > 10 lines213- **Exports**: Named exports only (no default)214- **File naming**: kebab-case.tsx215```216217### Common Patterns218219```markdown220## Patterns221222### Error Handling223```typescript224try {225 const result = await operation();226 toast.success('Operation completed');227 return result;228} catch (error) {229 const message = error instanceof Error ? error.message : 'Unknown error';230 toast.error(message);231 throw error; // Re-throw for caller to handle232}233```234235### API Route Structure236```typescript237// app/api/users/route.ts238export async function GET(request: Request) {239 try {240 // 1. Parse/validate input241 // 2. Check auth/permissions242 // 3. Perform operation243 // 4. Return Response244 } catch (error) {245 return new Response(JSON.stringify({ error: 'Message' }), {246 status: 500247 });248 }249}250```251```252253### What NOT to Include254255```markdown256# ❌ AVOID - Too obvious257- Write readable code258- Use meaningful variable names259- Add comments when necessary260- Follow best practices261262# ❌ AVOID - Too restrictive263- Never use any third-party libraries264- Always write everything from scratch265- Every function must be under 5 lines266267# ❌ AVOID - Language-agnostic advice268- Use design patterns269- Think before you code270- Test your code271```272273## Structure Template274275```markdown276# Project Name - Cursor Rules277278## Tech Stack279[List all major technologies]280281## Code Style282[Specific style decisions]283284## Project Structure285[Directory organization]286287## Patterns288[Common patterns with code examples]289290### Pattern Name291[Description]292```code example```293294## Conventions295[Project-specific conventions]296297## Common Tasks298[Frequent operations with snippets]299300### Task Name301```302step 1303step 2304```305306## Anti-Patterns307[What to avoid and why]308309## Testing310[Testing approach and patterns]311```312313## Example Sections314315### Tech Stack Section316317```markdown318## Tech Stack319320**Framework:** Next.js 14 (App Router)321**Language:** TypeScript 5.x (strict mode enabled)322**Styling:** Tailwind CSS 3.x with custom design system323**State:** Zustand for global, React Context for component trees324**Forms:** React Hook Form + Zod validation325**Database:** PostgreSQL with Prisma ORM326**Testing:** Vitest (unit), Playwright (E2E)327**Deployment:** Vercel328329**Key Dependencies:**330- `@tanstack/react-query` for server state331- `date-fns` for date manipulation (not moment.js)332- `clsx` + `tailwind-merge` for conditional classes333```334335### Patterns Section with Code336337```markdown338## Patterns339340### Server Component Data Fetching341342```typescript343// app/users/page.tsx344import { prisma } from '@/lib/prisma';345346export default async function UsersPage() {347 // Fetch directly in server component348 const users = await prisma.user.findMany({349 select: {350 id: true,351 name: true,352 email: true353 }354 });355356 return <UserList users={users} />;357}358```359360### Client Component with State361362```typescript363'use client';364365import { useState } from 'react';366import { toast } from 'sonner';367368interface FormProps {369 onSubmit: (data: FormData) => Promise<void>;370}371372export function Form({ onSubmit }: FormProps) {373 const [loading, setLoading] = useState(false);374375 async function handleSubmit(e: React.FormEvent) {376 e.preventDefault();377 setLoading(true);378379 try {380 await onSubmit(new FormData(e.target as HTMLFormElement));381 toast.success('Saved successfully');382 } catch (error) {383 const message = error instanceof Error ? error.message : 'Failed to save';384 toast.error(message);385 } finally {386 setLoading(false);387 }388 }389390 return (391 <form onSubmit={handleSubmit}>392 {/* form fields */}393 <button disabled={loading}>394 {loading ? 'Saving...' : 'Save'}395 </button>396 </form>397 );398}399```400```401402### Anti-Patterns Section403404```markdown405## Anti-Patterns406407### ❌ Don't: Default Exports408```typescript409// ❌ BAD410export default function Button() { }411412// ✅ GOOD413export function Button() { }414```415416**Why:** Named exports are more refactor-friendly and enable better tree-shaking.417418### ❌ Don't: Inline Type Definitions419```typescript420// ❌ BAD421function UserCard({ user }: { user: { name: string; email: string } }) { }422423// ✅ GOOD424interface User {425 name: string;426 email: string;427}428429function UserCard({ user }: { user: User }) { }430```431432**Why:** Reusability and discoverability.433434### ❌ Don't: Client Components for Static Content435```typescript436// ❌ BAD437'use client';438export function StaticContent() {439 return <div>Static text</div>;440}441442// ✅ GOOD - Server component by default443export function StaticContent() {444 return <div>Static text</div>;445}446```447448**Why:** Server components are faster and reduce bundle size.449```450451## Common Tasks452453Include shortcuts for frequent operations:454455```markdown456## Common Tasks457458### Adding a New API Route4594601. Create `app/api/[route]/route.ts`4612. Define HTTP method exports (GET, POST, etc.)4623. Validate input with Zod schema4634. Use try/catch for error handling4645. Return `Response` object465466```typescript467import { z } from 'zod';468469const schema = z.object({470 name: z.string().min(1)471});472473export async function POST(request: Request) {474 try {475 const body = await request.json();476 const data = schema.parse(body);477478 // Process...479480 return Response.json({ success: true });481 } catch (error) {482 if (error instanceof z.ZodError) {483 return Response.json(484 { error: error.errors },485 { status: 400 }486 );487 }488 return Response.json(489 { error: 'Internal error' },490 { status: 500 }491 );492 }493}494```495496### Adding a New Component4974981. Create `components/component-name.tsx`4992. Define props interface5003. Export as named export5014. Co-locate test if complex logic502503```typescript504// components/user-card.tsx505interface UserCardProps {506 name: string;507 email: string;508 onEdit?: () => void;509}510511export function UserCard({ name, email, onEdit }: UserCardProps) {512 return (513 <div className="rounded-lg border p-4">514 <h3 className="font-semibold">{name}</h3>515 <p className="text-sm text-gray-600">{email}</p>516 {onEdit && (517 <button onClick={onEdit}>Edit</button>518 )}519 </div>520 );521}522```523```524525## Best Practices526527### Keep Rules Under 500 Lines528529- Split large rules into multiple, composable files530- Each rule file should focus on one domain or concern531- Reference other rule files when needed (e.g., "See `backend-api.mdc` for API patterns")532- **Why:** Large files become unmanageable and harder for AI to process effectively533534### Split Into Composable Rules535536Break down by concern rather than creating one monolithic file:537538```539.cursor/rules/540 ├── tech-stack.mdc # Core technologies541 ├── typescript-patterns.mdc # Language-specific patterns542 ├── api-conventions.mdc # API route standards543 ├── component-patterns.mdc # React/UI patterns544 └── testing-standards.mdc # Testing approaches545```546547**Why:** Easier to maintain, update, and reuse across similar projects.548549### Provide Concrete Examples or Referenced Files550551Instead of vague guidance, always include:552- Complete, runnable code examples553- References to actual project files: `See components/auth/LoginForm.tsx for example`554- Links to internal docs or design system555- Specific file paths and line numbers when relevant556557**❌ BAD - Vague:**558```markdown559Use proper error handling in API routes.560```561562**✅ GOOD - Concrete:**563```markdown564API routes must use try/catch with typed errors. Example:565```typescript566// app/api/users/route.ts (lines 10-25)567export async function POST(request: Request) {568 try {569 const data = await request.json();570 return Response.json({ success: true });571 } catch (error) {572 return handleApiError(error); // See lib/errors.ts573 }574}575```576See `app/api/products/route.ts` for complete implementation.577```578579### Avoid Vague Guidance - Write Rules Like Clear Internal Docs580581Rules should read like technical documentation, not casual advice:582- Be precise and unambiguous583- Include the "why" behind decisions584- Document exceptions to rules585- Reference architecture decisions586- Link to related rules or documentation587588**Think:** "Could a new engineer understand this without asking questions?"589590### Reuse Rules When Repeating Prompts in Chat591592If you find yourself giving the same instructions repeatedly in chat:5931. Document that pattern in `.cursor/rules/`5942. Include the specific guidance you keep repeating5953. Add examples of correct implementation5964. Update existing rule files rather than creating new ones597598**Common scenarios to capture:**599- "Always use X pattern for Y"600- "Don't forget to Z when doing W"601- Corrections you make frequently602- Patterns specific to your team/codebase603604### Keep It Scannable605606- Use headers and sections607- Bold important terms608- Code examples for clarity609- Tables for comparisons610- Add table of contents for files over 200 lines611612### Update Regularly613614- Review monthly or after major changes615- Remove outdated patterns616- Add new patterns as they emerge617- Keep examples current618- Archive deprecated rules rather than deleting (for reference)619620### Test with AI621622Ask AI to:6231. "Create a new API route following our conventions"6242. "Add error handling to this component"6253. "Refactor this to match our patterns"626627Verify it follows your rules correctly.628629## Real-World Example630631See the PRPM registry `.cursor/rules` for a complete example:632- Clear tech stack declaration633- Specific TypeScript patterns634- Fastify-specific conventions635- Error handling standards636- API route patterns637638## Checklist for New Cursor Rules639640**YAML Frontmatter:**641- [ ] Title field present and descriptive642- [ ] Description field present (MANDATORY - never empty or `---`)643- [ ] Tags array includes relevant categories644- [ ] Optional fields (ruleType, alwaysApply, source) added if applicable645646**Project Context:**647- [ ] Tech stack clearly defined648- [ ] Version numbers specified649- [ ] Key dependencies listed650651**Code Style:**652- [ ] Component style specified (functional/class)653- [ ] Export style (named/default)654- [ ] File naming convention655- [ ] Specific to project (not generic)656657**Patterns:**658- [ ] At least 3 code examples659- [ ] Cover most common tasks660- [ ] Include error handling pattern661- [ ] Show project-specific conventions662663**Organization:**664- [ ] Logical section headers665- [ ] Scannable (not wall of text)666- [ ] Examples are complete and runnable667- [ ] Anti-patterns included668669**Testing:**670- [ ] Tested with AI assistant671- [ ] AI follows conventions correctly672- [ ] Updated after catching mistakes673674---675676**Remember:** Cursor rules are living documents. Update them as your project evolves and patterns emerge.677678```
One repository carrying more than one format is the comparison this product exists for: does anyone actually write different content in each file, or is one a copy of the other?
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| pr-pm/prpm.cursor/rules/testing-patterns.mdc · 121 | Cursor rules | testlint-formatstyletesting-strategy | 77/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/beanstalk-deploy.mdc · 121 | Cursor rules | teststyletypes | 62/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/core-principles.mdc · 121 | Cursor rules | testlint-formatstylearch+6 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-agents-md.mdc · 121 | Cursor rules | testlint-formatstylearch+7 | 92/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-skills.mdc · 121 | Cursor rules | stylearchtesting-strategydo-not+1 | 61/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/github-actions-testing.mdc · 121 | Cursor rules | setupbuildstylearch+4 | 93/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/karen-repo-reviewer.mdc · 121 | Cursor rules | archgit | 58/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/prpm-json-best-practices.mdc · 121 | Cursor rules | setuplint-formatstylearch+5 | 73/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/self-improve-cursor.mdc · 121 | Cursor rules | setuptestarchdependencies+3 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/typescript-type-safety.mdc · 121 | Cursor rules | buildstylearchtypes+2 | 89/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/typescript-type-specialist.mdc · 121 | Cursor rules | styletypesdo-notagent-behaviour | 65/100 | 14 days ago | |
| pr-pm/prpmAGENTS.md · 121 | AGENTS.md | setupbuildtestlint-format+12 | 84/100 | 14 days ago | |
| pr-pm/prpmCLAUDE.md · 121 | CLAUDE.md | teststylegitapi+2 | 69/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/creating-kiro-agents.mdc · 121 | Cursor rules | setupbuildteststyle+5 | 76/100 | 14 days ago | |
| pr-pm/prpm.cursor/rules/format-conversion.mdc · 121 | Cursor rules | testlint-formatstyledo-not+1 | 63/100 | 14 days ago |
Same format, overlapping stack, ranked by quality.
| Repository | Format | Stack | Covers | Score | Changed |
|---|---|---|---|---|---|
| hiromaily/go-crypto-wallet.cursor/rules/typescript.mdc · 126 | Cursor rules | setupbuildtestlint-format+6 | 100/100 | 14 days ago | |
| TechSquidTV/Hermes.cursor/rules/10-hermes-api.mdc · 46 | Cursor rules | testlint-formatstylearch+5 | 100/100 | 14 days ago | |
| Allymahmoud/case-intake-platform.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| dodgecfr/combatfilms-webapp.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| deifos/clipmira-subtitles.cursor/rules/frontend.mdc · 1 | Cursor rules | setuptestlint-formatstyle+7 | 99/100 | 14 days ago | |
| markstev/mark-starter.cursor/rules/frontend.mdc · 0 | Cursor rules | setuptestlint-formatstyle+6 | 99/100 | 14 days ago | |
| langflow-ai/langflow.cursor/rules/docs_development.mdc · 153k | Cursor rules | setupbuildtestlint-format+7 | 97/100 | 14 days ago | |
| bybren-llc/safe-agentic-workflow.cursor/rules/10-backend-python.mdc · 399 | Cursor rules | testlint-formatstylegit+4 | 97/100 | today |
A badge carrying the measured quality of the strongest agent config file in this repository, out of 100. It reads from this index every time somebody loads your page, so it changes when the measurement changes and there is nothing to keep up to date. Free, no account, and the value is not something you or we can set by hand.
[](https://rulestack.kynth.studio/configs/pr-pm-prpm-cursor-rules-creating-cursor-rules)Would rather not hotlink us? Every badge is also served in shields.io’s endpoint schema, so shields renders the image and your readers never talk to our domain:
Published by Toolproof, the masthead over this index and eight others. The method behind the number is at toolproof.kynth.studio/methodology, and the whole thing is readable as JSON with no key at /api.