Cursor Rules, .cursorrules, and Project Context That Sticks

How a single .cursorrules file keeps your AI coding tool grounded in your project's stack, conventions, and preferences — session after session.

Author:
Codapress Publishing
Date:

If you have used Cursor for more than a few sessions, you have probably repeated yourself. “We use React with TypeScript.” “No, we use Vitest, not Jest.” “Tailwind, not CSS Modules.” Every new chat resets the context, and you spend the first few messages re-establishing ground that the previous session already knew.

Cursor solves this with a config file that persists your project’s conventions so the model loads them automatically. It is called .cursorrules — and it may be the single highest-leverage file you create in any AI-assisted project.

What is a .cursorrules file?

A .cursorrules file sits at the root of your project directory and tells Cursor’s model how to behave inside that codebase. It is plain-text Markdown (no special syntax) that Cursor prepends to the system prompt at the start of each chat or Composer session. The model receives it as background context — not as user input, but as configuration — so it cannot be overridden mid-conversation.

Think of it as a permanent briefing document for every AI session in that project. Write it once, commit it to version control, and every team member (and every future-you) benefits from the same grounding.

Without .cursorrulesWith .cursorrules
Remind the model about your stack every sessionStack, linting, and testing tools already loaded
AI guesses conventions (often incorrectly)Conventions are listed explicitly
Follow-up messages re-explain constraintsModel honours constraints from message one
Context drifts between sessionsEvery session starts from the same prompt

The difference compounds. A developer who starts ten Cursor sessions per week saves twenty to thirty correction messages — roughly the same cognitive overhead as re-reading a project README every time.

What belongs in the file

Effective .cursorrules files cover the same ground as a project README — but aimed at a model rather than a human teammate. Humans need context to understand; models need context to generate correct output.

CategoryWhat to include
Stack and frameworksLanguage runtime, framework, major libraries with pinned versions
Testing toolsVitest, Jest, Playwright — and conventions (co-located tests, describe/it patterns)
Linting and formattingESLint config, Prettier settings, commit hook rules
Project structureWhere components live, how pages map to routes, shared utility locations
Styling approachTailwind, CSS Modules, styled-components, design tokens
Import patternsAbsolute vs relative imports, barrel files, path aliases
API conventionsError handling shape, auth method, data fetching strategy
Things to avoidDeprecated patterns, forbidden imports, libraries you evaluated and rejected

Hugging Face’s breakdown of system prompts in coding agents makes a related point: the more structured your project-level instructions, the less the model falls back on generic training data that may not match your stack.

A working example

Here is a .cursorrules file for a typical Next.js project.

You are an expert TypeScript and Next.js developer.

## Stack
- Next.js 15 (App Router), TypeScript strict mode
- Tailwind CSS for all styling
- Prisma ORM (Postgres)
- tRPC for type-safe API calls
- NextAuth v5 for authentication
- Vitest + React Testing Library for unit tests
- Playwright for E2E tests

## Project conventions
- Components go in `src/components/{name}/`
- Pages live in `src/app/` following App Router conventions
- Shared types in `src/types/`
- Utility functions in `src/lib/`
- API routes in `src/app/api/` using tRPC routers

## Code style
- Use named exports for components and utilities
- Prefer async server components over useEffect for data fetching
- Use Tailwind utility classes only (no CSS Modules or styled-components)
- Import paths use the `@/` alias for `src/`
- Error boundaries wrap every route group

## Testing
- Unit test files co-located with components as `*.test.tsx`
- Prefer testing behaviour over implementation details
- Playwright tests go in `e2e/` mirroring the route structure

## What to avoid
- Do not use `any` — use `unknown` and narrow with type guards
- Do not use useEffect for data fetching — use server components or tRPC queries
- Do not add new dependencies without checking if the team already has a solution

This file tells the model everything it needs to generate code that fits the project on the first attempt. No reminder messages, no “we use this, not that.”

How to generate your own rules file

You do not have to write the file from memory. Ask Cursor to reverse-engineer your project.

Analyse this project and create a .cursorrules file that captures:
- The framework, runtime, and major libraries in use
- The testing and linting tools configured in package.json
- The project directory structure (where components, pages, utils live)
- Any coding patterns visible across the codebase (import style, error handling, data fetching)
- Conventions in existing tests (file location, naming, assertion style)

Write the output as a .cursorrules file I can place at the project root.

The model will scan your codebase, infer patterns, and produce a first draft. Review it, trim anything it misunderstood, and add nuances only you know — like “we prefer infinite queries over pagination” or “do not generate barrel files.”

The rules hierarchy

Cursor reads .cursorrules from the project root, but also supports a layered system for finer-grained control. The lookup order is: global ~/.cursorrules → project .cursorrules → folder-level .cursor/rules/*.mdc. Each layer appends or overrides context for its scope.

LevelFile locationScope
Global~/.cursorrulesEvery project on your machine
Project./.cursorrulesA single repository
Folder.cursor/rules/*.mdcA subdirectory (e.g. apps/web/)

Folder-level rules shine in monorepos. A monorepo with a React frontend, a Go backend, and a shared types package can define separate rules for each directory so the model uses the right conventions in the right context.

Common mistakes

The most frequent error is writing rules that are too vague. “Write clean code” tells the model nothing. “Use early returns instead of nested if statements” tells it exactly how to behave. Vague preferences produce the same inconsistency you would get without the file.

Another mistake is overloading the file. A .cursorrules file that runs to three pages of prohibitions becomes a wall of noise. The model will still read it — but the signal-to-noise ratio drops, and the most important constraints lose weight. Aim for one page of concise, action-oriented rules.

A third is treating the file as a one-time effort. Projects evolve; rules files should too. When you adopt a new library, retire an old convention, or discover the model repeatedly misinterprets a pattern, update the file. Keep it in version control and review it during PRs alongside code changes.

Making context stick

The .cursorrules file is the foundation of Cursor’s context system, but it works best alongside good project structure. Consistent file naming, clear folder boundaries, and a well-maintained README all contribute to a codebase that an AI can navigate accurately.

Teams that get the most out of Cursor treat context management as a first-class discipline — not something you improvise in the chat window. A good .cursorrules file saves you from repeating yourself, keeps the model grounded in your project’s reality, and makes every Cursor session productive from the opening message.

For a complete reference on configuring Cursor for your workflow, see A Simple Guide to Cursor. If you are managing rules across a team, Cursor Pro covers multi-user setups, shared rule repositories, and CI validation of AI-generated code against team conventions.

More insights

All Articles