TL;DR: Cursor Rules are instructions you write in a .cursorrules file (or the newer .cursor/rules/ directory) that tell Cursor's AI how to behave in your project. They persist across every conversation — so you stop repeating "use Tailwind, not vanilla CSS" in every prompt. You define your stack, coding style, naming conventions, and project quirks once. Cursor reads them automatically. Think of it as training a new teammate on day one, except the teammate has perfect recall.
Why Every AI Coder Needs a Rules File
Here's the frustrating pattern. You open Cursor, start a new chat, and ask it to build a component. It gives you something that works — but it's not your style. It used var instead of const. It imported from a library you don't use. It wrote CSS in a separate file when your whole project uses Tailwind classes inline.
So you correct it. "Actually, use Tailwind." "Actually, use TypeScript." "Actually, we use Supabase, not Firebase." And it adjusts. But tomorrow, you start a new conversation and go through the whole thing again.
This is the single biggest time sink for AI coders who don't know about rules files. You're spending 10-15% of every conversation re-establishing context that should have been set once.
A .cursorrules file fixes this permanently. It's a plain text file that sits in your project root and tells Cursor: "Here's how this project works. Follow these rules in every conversation, no exceptions."
If you've used Claude Code: Cursor Rules serve the same purpose as the CLAUDE.md file inside the .claude/ folder. Different tool, same concept — persistent instructions that load automatically every session.
The difference between a project with rules and one without is dramatic. Without rules, Cursor is a capable but generic assistant. With rules, it becomes your assistant — one that already knows your stack, your preferences, and the weird quirks of your specific project.
The Real Scenario: "Build Me a Contact Form"
Let's make this concrete. Say you're building a Next.js app with Tailwind CSS, TypeScript, and Supabase. You've been working on it for a week. Now you need a contact form.
What you type in Cursor:
"Build a contact form component that saves submissions to my database"
Without a rules file, Cursor might give you:
- A JavaScript file (not TypeScript)
- Styled with a separate CSS module
- Using
fetchto hit a generic REST endpoint - Class-based form validation
- No error handling pattern matching your existing code
It's not wrong. It just doesn't match your project at all. You'd spend 20 minutes refactoring it to fit.
With a rules file, the same prompt produces:
- A
.tsxTypeScript component - Styled with Tailwind utility classes
- Using your Supabase client to insert into the
submissionstable - Zod schema for validation (because your rules say so)
- Error handling that matches the pattern used everywhere else in your app
Same prompt. Dramatically different output. The only difference is a text file in your project root.
What a Real .cursorrules File Looks Like
Here's a real-world example for a Next.js + Tailwind + Supabase project. This is the kind of file that saves you hours every week:
# Project: My SaaS App
# Stack: Next.js 14 (App Router), TypeScript, Tailwind CSS, Supabase
## General Rules
- Always use TypeScript (.tsx for components, .ts for utilities)
- Use functional components with arrow function syntax
- Prefer named exports over default exports
- Use 'const' exclusively — never 'let' or 'var' unless mutation is required
## Styling
- Use Tailwind CSS utility classes exclusively — no CSS modules, no styled-components
- Follow mobile-first responsive design (sm: md: lg: breakpoints)
- Use the project's design tokens from tailwind.config.ts
## Database & Backend
- Use Supabase client from '@/lib/supabase' for all database operations
- Always handle errors with try/catch and return user-friendly messages
- Use Zod schemas for all form validation (schemas live in @/lib/schemas/)
- Server actions go in the same file as the component that uses them
## File Organization
- Components: @/components/{feature}/{ComponentName}.tsx
- Utilities: @/lib/{name}.ts
- Types: @/types/{name}.ts
- API routes: @/app/api/{route}/route.ts
## Naming Conventions
- Components: PascalCase (ContactForm.tsx)
- Files/folders: kebab-case (contact-form/)
- Variables/functions: camelCase
- Database columns: snake_case
- Environment variables: UPPER_SNAKE_CASE
## Things to Avoid
- Do NOT use Firebase, Prisma, or any ORM other than Supabase client
- Do NOT create separate CSS files
- Do NOT use 'any' type — always define proper TypeScript types
- Do NOT use class components
- Do NOT use relative imports — use the @/ path alias
That's it. Plain text. No special syntax, no YAML, no JSON. Just instructions written in a way that an AI can understand — which, conveniently, is the same way a human can understand them.
Understanding Each Part of the Rules File
Let's break down what each section does and why it matters.
The Header: Project Context
The top of your rules file tells Cursor what it's working with. This isn't just documentation — it fundamentally changes what code Cursor generates. When it knows you're using Next.js 14 with App Router, it won't accidentally give you Pages Router patterns. When it knows you're on TypeScript, every file it creates will have proper types.
General Rules: Your Coding DNA
These are the rules that apply to everything. Functional components, named exports, const over let — these are the decisions you've already made for this project. Without them, Cursor has to guess. And its guesses are based on the entire internet's worth of code, not your specific preferences.
Styling: How Things Look
This is where the "Cursor keeps suggesting vanilla CSS" problem gets solved. One line — "Use Tailwind CSS utility classes exclusively" — and Cursor never generates a .css file again for this project. It knows. Every component it creates will use Tailwind classes.
Database & Backend: How Data Moves
If your project uses Supabase but Cursor keeps suggesting Firebase or raw SQL, this section fixes that. You're telling Cursor: "We have a specific way of handling data in this project. Use it." This includes error handling patterns, validation libraries, where server actions live — the backend architecture that Cursor can't infer from a single prompt.
File Organization: Where Things Go
This might be the most underrated section. Without it, Cursor will put files wherever seems reasonable. With it, every new component lands in exactly the right folder with exactly the right naming pattern. Your project stays organized even as an AI writes most of the code.
Things to Avoid: The Guardrails
This section is powerful. Telling Cursor what not to do is often more effective than telling it what to do. "Do NOT use any type" prevents the lazy shortcut that makes TypeScript pointless. "Do NOT create separate CSS files" stops a habit that Cursor defaults to without Tailwind rules.
Keep it focused. A rules file works best at 30–100 lines. If yours is growing past 150 lines, you're probably including task-specific instructions that belong in your prompts, not your rules. Rules are for project-wide constants — things that are true for every single conversation.
The New Way: .cursor/rules/ Directory
Cursor is evolving. While .cursorrules still works, the newer approach uses a .cursor/rules/ directory with individual rule files. This gives you more control.
Each file inside .cursor/rules/ is a separate rule set. The magic is that each one can be scoped to specific file patterns — meaning rules only activate when you're working on matching files.
.cursor/
rules/
general.mdc # Always active
frontend.mdc # Active for .tsx, .jsx files
api-routes.mdc # Active for app/api/**
testing.mdc # Active for *.test.ts, *.spec.ts
database.mdc # Active for lib/db/**, lib/supabase/**
Each .mdc file has a frontmatter section at the top that defines when it activates:
---
description: Frontend component conventions
globs: ["**/*.tsx", "**/*.jsx"]
alwaysApply: false
---
# Frontend Rules
- Use functional components with arrow syntax
- Style with Tailwind utility classes
- Keep components under 150 lines — extract sub-components when needed
Why does this matter? Because your testing rules are irrelevant when you're building a component. Your database conventions don't matter when you're writing CSS. Path-scoped rules keep Cursor focused on what's relevant, which means better output and less context wasted on rules that don't apply.
When to Use Which Format
| Scenario | Use This |
|---|---|
| Small project, simple rules | .cursorrules (single file) |
| Large project, many conventions | .cursor/rules/ (directory) |
| Monorepo with different stacks | .cursor/rules/ with path scoping |
| Team project with shared rules | Either — commit to git either way |
Project-Specific vs. Global Rules
Cursor supports rules at two levels:
Project-level (.cursorrules or .cursor/rules/) — Lives in your project root. These are specific to this codebase. "Use Supabase" belongs here because your next project might use Firebase.
Global (Cursor Settings → Rules for AI) — Applies to every project you open in Cursor. These are your personal coding preferences that don't change between projects. Things like "always add comments explaining why, not what" or "prefer early returns over nested if statements."
Rule of thumb: If you'd want this rule in every project you'll ever work on, it's global. If it's about this specific project's stack, libraries, or conventions, it's project-level. When in doubt, make it project-level — you can always promote it to global later.
What Happens When Rules Conflict?
If your global rules say "use semicolons" and your project rules say "no semicolons," the project rules win. Cursor applies rules in this priority order:
- Your current prompt — always highest priority
- Project-level rules (
.cursorrulesor.cursor/rules/) - Global rules (Cursor Settings)
This is the right hierarchy. Your prompt captures what you need right now. Project rules capture what this codebase needs. Global rules capture your baseline preferences. When they disagree, the more specific context wins.
What AI Gets Wrong About Cursor Rules
If you ask ChatGPT or Claude to write you a .cursorrules file, they'll usually give you something that works — but has common issues:
Too Vague
Bad: "Write clean code."
Good: "Use named exports. Keep functions under 30 lines. Extract helper functions into separate files when they're reused."
Cursor can't act on "write clean code." That means nothing to an AI. Specific, actionable rules produce specific, consistent output.
Too Long
AI loves to generate comprehensive documentation. A 500-line rules file sounds thorough, but it actually hurts performance. Every token in your rules file is context that Cursor loads into every conversation. A bloated rules file means less room for the actual task. Aim for 30–100 lines of high-signal rules.
Too Obvious
Bad: "Use proper indentation." "Write valid JavaScript."
Cursor already does these things. Your rules file should contain the things Cursor would get wrong without guidance. The whole point is correcting default behavior, not restating what any competent AI already does.
Missing the "Don't" Rules
AI-generated rules files almost never include negative rules. But "do NOT use Firebase" is often more valuable than "use Supabase." Negative rules create hard boundaries. Positive rules create preferences. Both matter, but most people forget the negatives.
The biggest mistake: Putting task instructions in your rules file. "Build the login page using the Auth component" is a prompt, not a rule. Rules define how code should be written. Prompts define what to build. Mixing them up clutters your rules with one-time instructions that don't apply to anything else.
How to Know If Your Rules Are Working
You set up a rules file. How do you know Cursor is actually reading it? Here are the debugging steps:
1. The Direct Test
Open a new Cursor chat and ask: "What are my project rules?" or "Summarize the .cursorrules file for this project." Cursor should be able to describe your rules back to you. If it can't, the file isn't being loaded.
2. The Contradiction Test
If your rules say "use Tailwind," ask Cursor to build a styled component without mentioning Tailwind in your prompt. Does it use Tailwind automatically? If yes, your rules are working. If it falls back to vanilla CSS, something's wrong.
3. Common Problems
File is in the wrong location. The .cursorrules file must be in the project root — the folder you opened in Cursor. Not in src/, not in a subfolder. Right next to your package.json.
File has the wrong name. It's .cursorrules — no extension, no capital letters. Not cursorrules.txt, not .cursorRules, not cursor-rules.md.
Rules are too vague to test. "Write good code" will never produce a visible change. "Always use const instead of let" is immediately testable.
Cursor is using an older model. Newer models follow rules more reliably. If you're on an older model, you might see more rule-breaking. Check your model selection in Cursor settings.
4. When Rules Get Ignored
Even with a perfect rules file, Cursor will occasionally ignore a rule. This happens when:
- Your prompt explicitly contradicts the rule (prompt wins, by design)
- The conversation is very long and the rules have faded from context
- The rule conflicts with what the model considers correct (e.g., a rule that would produce buggy code)
If a rule keeps getting ignored, try making it more explicit, moving it higher in the file, or rephrasing it as a negative rule ("do NOT..."). If you want to learn more about effective prompting that works alongside rules, check out our AI prompting guide for coders.
Common Rule Patterns Worth Stealing
Here are battle-tested rule patterns for popular stacks. Use these as starting points, then customize for your project.
For React/Next.js Projects
- Use functional components with arrow syntax
- Prefer server components; only add 'use client' when needed
- Use Next.js App Router conventions (not Pages Router)
- Co-locate related files (component, types, tests in same directory)
- Use next/image for all images, next/link for all internal links
For Python/FastAPI Projects
- Use Python 3.12+ features (type hints, match statements)
- Follow PEP 8 strictly
- Use Pydantic v2 models for all request/response schemas
- Use async/await for all database operations
- Organize routes in routers/ directory, one file per resource
For Any Project (Good Defaults)
- Add brief comments explaining WHY, not what
- Handle errors explicitly — never silently catch and ignore
- When creating new files, check for existing patterns first
- Prefer composition over inheritance
- Keep functions focused — one function, one job
For a broader look at setting up Cursor from scratch and understanding all its features, see our Cursor beginner's guide.
How This Compares to Other AI Editors
Every serious AI code editor now has some version of this concept:
| Editor | Rules File | Path Scoping |
|---|---|---|
| Cursor | .cursorrules or .cursor/rules/ |
Yes (in .mdc files) |
| Claude Code | CLAUDE.md + .claude/rules/ |
Yes |
| Windsurf | .windsurfrules |
Limited |
| GitHub Copilot | .github/copilot-instructions.md |
No |
The concept is identical across all of them: give the AI persistent context about your project so you stop repeating yourself. The implementation details vary, but the strategy is the same. If you're comparing editors, our Cursor vs. Windsurf comparison covers the differences in depth.
What's Next
You now understand what Cursor Rules are, how to create them, and how to debug them when they're not working. Here's your action plan:
- Create your first rules file. Open your project root. Create a file called
.cursorrules. Add 5-10 rules about your stack and coding style. Start small — you can always add more. - Test it immediately. Open a new Cursor chat and ask it to build something without specifying your stack in the prompt. Does it follow your rules? If yes, you're golden.
- Iterate over the next week. Every time Cursor does something you don't want, ask yourself: "Should this be a rule?" If yes, add it to the file.
- Commit it to git. Your teammates (or future you) will thank you. A shared rules file means consistent AI-generated code across the whole team.
- Explore the directory format. Once your single file hits 80+ lines, consider splitting into
.cursor/rules/with path-scoped rule files.
The difference between a good AI coder and a great one often comes down to this: the great one configured their tools properly before writing a single prompt. Rules files are the highest-leverage thing you can do in Cursor — ten minutes of setup that saves hours every week.
If you're also using VS Code alongside Cursor, check out our guide on setting up VS Code for AI-assisted coding — a lot of the extensions and configuration concepts carry over.
Frequently Asked Questions
What is a .cursorrules file?
It's a plain text file in your project's root directory that tells Cursor's AI how to behave. Your preferred coding style, which libraries to use, naming conventions, file organization — anything you'd normally have to repeat in every conversation. Cursor reads it automatically when you open the project, and the rules stay active for every chat session.
Where do I put my Cursor rules file?
In the root of your project — the same folder as your package.json, README.md, or whatever top-level config files you have. The file should be named exactly .cursorrules (with the dot, no file extension). For the newer directory format, create .cursor/rules/ in the same location and add .mdc files inside it.
What's the difference between .cursorrules and .cursor/rules/?
The .cursorrules file is the original, simpler approach — one file with all your rules. The .cursor/rules/ directory is the newer format that lets you split rules into multiple files, each scoped to specific file patterns. For example, you could have frontend rules that only activate when you're editing .tsx files, and database rules that only activate for files in your lib/db/ directory. Both formats work. The directory approach gives you more precision for larger projects.
Do Cursor rules replace good prompting?
No — they complement each other. Rules handle the constants: your stack, coding style, conventions, and guardrails. Prompts handle the variables: what you need built right now. A good rules file means your prompts can be shorter and more focused because the baseline context is already established. For tips on writing better prompts that work alongside your rules, see our AI prompting guide.
Can I use someone else's .cursorrules file?
Absolutely. Sites like cursor.directory have community-shared rules files for common stacks — Next.js, Python, React Native, and more. They're a great starting point. But always customize them for your specific project. A generic "Next.js rules" file won't know that your project uses Supabase instead of Prisma, or that you organize components by feature rather than by type. Start with a template, then make it yours.