Expert guidance for creating effective Cursor IDE rules with best practices, patterns, and examples
Install via CLI
openskills install pr-pm/prpm---
name: creating-cursor-rules-skill
description: Expert guidance for creating effective Cursor IDE rules with best practices, patterns, and examples
---
# Creating Cursor Rules
You are an expert at creating effective `.cursor/rules` files that help AI assistants understand project conventions and produce better code.
## When to Apply This Skill
**Use when:**
- User is starting a new project and needs `.cursor/rules` setup
- User wants to improve existing project rules
- User asks to convert skills/guidelines to Cursor format
- Team needs consistent coding standards documented
**Don't use for:**
- One-time instructions (those can be asked directly)
- User-specific preferences (those go in global settings)
- Claude Code skills (this skill is specifically for Cursor rules)
## Core Principles
### 1. Be Specific and Actionable
Rules should provide concrete guidance, not vague advice.
**❌ BAD - Vague:**
```markdown
Write clean code with good practices.
Use proper TypeScript types.
```
**✅ GOOD - Specific:**
```markdown
Use functional components with TypeScript.
Define prop types with interfaces, not inline types.
Extract custom hooks when logic exceeds 10 lines.
```
### 2. Focus on Decisions, Not Basics
Don't document what linters handle. Document architectural decisions.
**❌ BAD - Linter territory:**
```markdown
Use semicolons in JavaScript.
Indent with 2 spaces.
Add trailing commas.
```
**✅ GOOD - Decision guidance:**
```markdown
Choose Zustand for global state, React Context for component trees.
Use Zod for runtime validation at API boundaries only.
Prefer server components except for: forms, client-only APIs, animations.
```
### 3. Organize by Concern
Group related rules into clear sections:
```markdown
## Tech Stack
- Next.js 14 with App Router
- TypeScript strict mode
- Tailwind CSS for styling
## Code Style
- Functional components only
- Named exports (no default exports)
- Co-locate tests with source files
## Patterns
- Use React Server Components by default
- Client components: mark with "use client" directive
- Error handling: try/catch + toast notification
## Project Conventions
- API routes in app/api/
- Components in components/ (flat structure)
- Types in types/ (shared), components/*/types.ts (local)
```
## Rule Anatomy
### MDC Format and Metadata
Cursor rules are written in **MDC (.mdc)** format, which supports YAML frontmatter metadata and markdown content. The metadata controls how and when rules are applied.
### Required YAML Frontmatter
Every Cursor rule MUST start with YAML frontmatter between `---` markers:
```yaml
---
description: Brief description of when and how to use this rule
globs: ["**/*.ts", "**/*.tsx"]
alwaysApply: false
---
```
### Frontmatter Properties
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `description` | string | **Yes** | Brief description of the rule's purpose. Used by AI to decide relevance. Never use placeholders like `---` or empty strings. |
| `globs` | array | No | File patterns that trigger auto-attachment (e.g., `["**/*.ts"]`). Leave empty or omit if not using Auto Attached type. |
| `alwaysApply` | boolean | No | If `true`, rule is always included in context. If `false` or omitted, behavior depends on Rule Type. |
### Rule Types
Control how rules are applied using the **type dropdown** in Cursor:
| Rule Type | Description | When to Use |
|-----------|-------------|-------------|
| **Always** | Always included in model context | Core project conventions, tech stack, universal patterns that apply everywhere |
| **Auto Attached** | Included when files matching `globs` pattern are referenced | File-type specific rules (e.g., React components, API routes, test files) |
| **Agent Requested** | Available to AI, which decides whether to include it based on `description` | Contextual patterns, specialized workflows, optional conventions |
| **Manual** | Only included when explicitly mentioned using `@ruleName` | Rarely-used patterns, experimental conventions, legacy documentation |
### Examples by Rule Type
**Always Rule** (Core conventions):
```yaml
---
description: TypeScript and code style conventions for the entire project
alwaysApply: true
---
```
**Auto Attached Rule** (File pattern-specific):
```yaml
---
description: React component patterns and conventions
globs: ["**/components/**/*.tsx", "**/app/**/*.tsx"]
alwaysApply: false
---
```
**Agent Requested Rule** (Contextual):
```yaml
---
description: RPC service boilerplate and patterns for creating new RPC endpoints
globs: []
alwaysApply: false
---
```
**Manual Rule** (Explicit invocation):
```yaml
---
description: Legacy API migration patterns (deprecated, use for reference only)
globs: []
alwaysApply: false
---
```
### Best Practices for Frontmatter
1. **Description is mandatory** - AI uses this to determine relevance. Be specific:
- ❌ Bad: `Backend code`
- ✅ Good: `Fastify API route patterns, error handling, and validation using Zod`
2. **Use globs strategically** - Auto-attach to relevant file types:
- React components: `["**/*.tsx", "**/*.jsx"]`
- API routes: `["**/api/**/*.ts", "**/routes/**/*.ts"]`
- Tests: `["**/*.test.ts", "**/*.spec.ts"]`
3. **Avoid always applying everything** - Use `alwaysApply: true` sparingly:
- ✅ Good for: Tech stack, core conventions, project structure
- ❌ Bad for: Framework-specific patterns, specialized workflows
4. **Make Agent Requested rules discoverable** - Write descriptions that help AI understand when to use:
- Include keywords: "boilerplate", "template", "pattern for X"
- Mention specific use cases: "when creating new API routes"
## Required Sections
Every Cursor rule file should include these sections:
### 1. Tech Stack Declaration
```markdown
## Tech Stack
- Framework: Next.js 14
- Language: TypeScript 5.x (strict mode)
- Styling: Tailwind CSS 3.x
- State: Zustand
- Database: PostgreSQL + Prisma
- Testing: Vitest + Playwright
```
**Why:** Prevents AI from suggesting wrong tools/patterns.
### 2. Code Style Guidelines
```markdown
## Code Style
- **Components**: Functional with TypeScript
- **Props**: Interface definitions, destructure in params
- **Hooks**: Extract when logic > 10 lines
- **Exports**: Named exports only (no default)
- **File naming**: kebab-case.tsx
```
### 3. Common Patterns
Always include code examples, not just descriptions:
```markdown
## Patterns
### Error Handling
```typescript
try {
const result = await operation();
toast.success('Operation completed');
return result;
} catch (error) {
const message = error instanceof Error ? error.message : 'Unknown error';
toast.error(message);
throw error; // Re-throw for caller to handle
}
```
### API Route Structure
```typescript
// app/api/users/route.ts
export async function GET(request: Request) {
try {
// 1. Parse/validate input
// 2. Check auth/permissions
// 3. Perform operation
// 4. Return Response
} catch (error) {
return new Response(JSON.stringify({ error: 'Message' }), {
status: 500
});
}
}
```
```
## What NOT to Include
Avoid these common mistakes:
**❌ Too obvious:**
```markdown
- Write readable code
- Use meaningful variable names
- Add comments when necessary
- Follow best practices
```
**❌ Too restrictive:**
```markdown
- Never use any third-party libraries
- Always write everything from scratch
- Every function must be under 5 lines
```
**❌ Language-agnostic advice:**
```markdown
- Use design patterns
- Think before you code
- Test your code
- Keep it simple
```
## Structure Template
Use this template for new Cursor rules:
```markdown
# Project Name - Cursor Rules
## Tech Stack
[List all major technologies with versions]
## Code Style
[Specific style decisions]
## Project Structure
[Directory organization]
## Patterns
[Common patterns with code examples]
### Pattern Name
[Description + code example]
## Conventions
[Project-specific conventions]
## Common Tasks
[Frequent operations with step-by-step snippets]
### Task Name
1. Step one
2. Step two
[Code example]
## Anti-Patterns
[What to avoid and why]
## Testing
[Testing approach and patterns with examples]
```
## Example Sections
### Tech Stack Section
```markdown
## Tech Stack
**Framework:** Next.js 14 (App Router)
**Language:** TypeScript 5.x (strict mode enabled)
**Styling:** Tailwind CSS 3.x with custom design system
**State:** Zustand for global, React Context for component trees
**Forms:** React Hook Form + Zod validation
**Database:** PostgreSQL with Prisma ORM
**Testing:** Vitest (unit), Playwright (E2E)
**Deployment:** Vercel
**Key Dependencies:**
- `@tanstack/react-query` for server state
- `date-fns` for date manipulation (not moment.js)
- `clsx` + `tailwind-merge` for conditional classes
```
### Anti-Patterns Section
```markdown
## Anti-Patterns
### ❌ Don't: Default Exports
```typescript
// ❌ BAD
export default function Button() { }
// ✅ GOOD
export function Button() { }
```
**Why:** Named exports are more refactor-friendly and enable better tree-shaking.
### ❌ Don't: Inline Type Definitions
```typescript
// ❌ BAD
function UserCard({ user }: { user: { name: string; email: string } }) { }
// ✅ GOOD
interface User {
name: string;
email: string;
}
function UserCard({ user }: { user: User }) { }
```
**Why:** Reusability and discoverability.
```
## Common Tasks
Include shortcuts for frequent operations:
```markdown
## Common Tasks
### Adding a New API Route
1. Create `app/api/[route]/route.ts`
2. Define HTTP method exports (GET, POST, etc.)
3. Validate input with Zod schema
4. Use try/catch for error handling
5. Return `Response` object
```typescript
import { z } from 'zod';
const schema = z.object({
name: z.string().min(1)
});
export async function POST(request: Request) {
try {
const body = await request.json();
const data = schema.parse(body);
// Process...
return Response.json({ success: true });
} catch (error) {
if (error instanceof z.ZodError) {
return Response.json(
{ error: error.errors },
{ status: 400 }
);
}
return Response.json(
{ error: 'Internal error' },
{ status: 500 }
);
}
}
```
```
## Best Practices
### Keep Rules Under 500 Lines
- Split large rules into multiple, composable files
- Each rule file should focus on one domain or concern
- Reference other rule files when needed (e.g., "See `backend-api.mdc` for API patterns")
- **Why:** Large files become unmanageable and harder for AI to process effectively
### Split Into Composable Rules
Break down by concern rather than creating one monolithic file:
```
.cursor/rules/
├── tech-stack.mdc # Core technologies
├── typescript-patterns.mdc # Language-specific patterns
├── api-conventions.mdc # API route standards
├── component-patterns.mdc # React/UI patterns
└── testing-standards.mdc # Testing approaches
```
**Why:** Easier to maintain, update, and reuse across similar projects.
### Provide Concrete Examples or Referenced Files
Instead of vague guidance, always include:
- Complete, runnable code examples
- References to actual project files: `See components/auth/LoginForm.tsx for example`
- Links to internal docs or design system
- Specific file paths and line numbers when relevant
**❌ BAD - Vague:**
```markdown
Use proper error handling in API routes.
```
**✅ GOOD - Concrete:**
```markdown
API routes must use try/catch with typed errors. Example:
```typescript
// app/api/users/route.ts (lines 10-25)
export async function POST(request: Request) {
try {
const data = await request.json();
return Response.json({ success: true });
} catch (error) {
return handleApiError(error); // See lib/errors.ts
}
}
```
See `app/api/products/route.ts` for complete implementation.
```
### Write Rules Like Clear Internal Docs
Rules should read like technical documentation, not casual advice:
- Be precise and unambiguous
- Include the "why" behind decisions
- Document exceptions to rules
- Reference architecture decisions
- Link to related rules or documentation
**Think:** "Could a new engineer understand this without asking questions?"
### Reuse Rules When Repeating Prompts
If you find yourself giving the same instructions repeatedly in chat:
1. Document that pattern in `.cursor/rules/`
2. Include the specific guidance you keep repeating
3. Add examples of correct implementation
4. Update existing rule files rather than creating new ones
**Common scenarios to capture:**
- "Always use X pattern for Y"
- "Don't forget to Z when doing W"
- Corrections you make frequently
- Patterns specific to your team/codebase
### Keep It Scannable
- Use clear section headers
- Bold important terms
- Include code examples (not just prose)
- Use tables for comparisons
- Add table of contents for files over 200 lines
### Update Regularly
- Review monthly or after major changes
- Remove outdated patterns
- Add new patterns as they emerge
- Keep examples current with latest framework versions
- Archive deprecated rules rather than deleting (for reference)
### Test with AI
After creating rules, test them:
1. Ask AI: "Create a new API route following our conventions"
2. Ask AI: "Add error handling to this component"
3. Ask AI: "Refactor this to match our patterns"
Verify AI follows rules correctly. Update rules based on gaps found.
## Real-World Example
The PRPM registry `.cursor/rules` demonstrates:
- Clear tech stack declaration (Fastify, TypeScript, PostgreSQL)
- Specific TypeScript patterns
- Fastify-specific conventions
- Error handling standards
- API route patterns
- Database query patterns
## Checklist for New Cursor Rules
**Project Context:**
- [ ] Tech stack clearly defined with versions
- [ ] Key dependencies listed
- [ ] Deployment platform specified
**Code Style:**
- [ ] Component style specified (functional/class)
- [ ] Export style (named/default)
- [ ] File naming convention
- [ ] Specific to project (not generic advice)
**Patterns:**
- [ ] At least 3-5 code examples
- [ ] Cover most common tasks
- [ ] Include error handling pattern
- [ ] Show project-specific conventions
**Organization:**
- [ ] Logical section headers
- [ ] Scannable (not wall of text)
- [ ] Examples are complete and runnable
- [ ] Anti-patterns included with rationale
**Testing:**
- [ ] Tested with AI assistant
- [ ] AI follows conventions correctly
- [ ] Updated after catching mistakes
## Helpful Prompts for Users
When helping users create Cursor rules:
**Discovery:**
- "What's your tech stack?"
- "What patterns do you want AI to follow?"
- "What mistakes does AI currently make?"
**Refinement:**
- "Are there anti-patterns you want documented?"
- "What are your most common coding tasks?"
- "Do you have naming conventions?"
**Validation:**
- "Let me test these rules by asking you to generate code..."
- "Does this match your team's style?"
## Remember
- Cursor rules are **living documents** - update as project evolves
- Focus on **decisions**, not basics
- Include **runnable code examples**, not descriptions
- Test rules with AI to verify effectiveness
- Keep it **scannable** - use headers, bold, lists
**Goal:** Help AI produce code that matches project conventions without constant correction.
No comments yet. Be the first to comment!