How to Set Up Cursor Rules Files (.cursorrules) for Team-Wide Code Style Enforcement Across Monorepo Projects
Why Cursor Rules Files Matter in Monorepo Projects
When multiple teams collaborate within a monorepo, maintaining consistent code style becomes a significant challenge. Cursor Rules files (.cursorrules) provide a powerful mechanism to enforce coding standards, naming conventions, and architectural patterns directly within the Cursor AI editor. Unlike traditional linters, these rules guide the AI assistant itself, ensuring every code suggestion and generation follows your team’s conventions from the start.
This guide walks you through setting up a hierarchical .cursorrules configuration that scales across packages, services, and teams in a monorepo environment.
Step 1: Understand the Cursor Rules File Hierarchy
Cursor resolves rules files from the most specific directory upward to the project root. This means you can define global rules at the root and override them per package.
monorepo/
├── .cursorrules # Global rules (applies everywhere)
├── packages/
│ ├── frontend/
│ │ └── .cursorrules # Frontend-specific overrides
│ ├── backend/
│ │ └── .cursorrules # Backend-specific overrides
│ └── shared/
│ └── .cursorrules # Shared library rules
└── services/
└── api-gateway/
└── .cursorrules # Service-specific rules
Rules in child directories take precedence over parent directories, giving you granular control without duplication.
Step 2: Create the Root-Level .cursorrules File
Start with a global rules file at the monorepo root. This sets the baseline for all teams.
# .cursorrules (monorepo root)
Project Overview
This is a TypeScript monorepo managed with Turborepo and pnpm workspaces.
General Code Style
- Use TypeScript strict mode in all packages.
- Prefer named exports over default exports.
- Use camelCase for variables and functions, PascalCase for types and components.
- All functions must have explicit return types.
- Maximum file length: 300 lines. Split larger files into modules.
- Use absolute imports with the @company/ prefix defined in tsconfig paths.
Error Handling
- Never use bare try/catch without logging.
- Use custom error classes extending BaseError from @company/shared.
- Always include error context with structured metadata.
Testing
- Every public function must have at least one unit test.
- Use describe/it blocks with clear, behavior-driven names.
- Test files live next to source files with .test.ts suffix.
Git Conventions
- Commit messages follow Conventional Commits (feat:, fix:, chore:, etc.).
PR descriptions must reference the relevant ticket ID.
Step 3: Add Package-Specific Rules
Create targeted rules files for each major package. These inherit the root rules and add domain-specific guidance.
Frontend Package Rules
# packages/frontend/.cursorrules
Framework
This package uses React 19 with Next.js App Router.
Component Conventions
- Use functional components exclusively.
- Place components in folders: ComponentName/index.tsx + ComponentName.test.tsx.
- Use CSS Modules for styling. File naming: ComponentName.module.css.
- Props interfaces must be named {ComponentName}Props.
- Prefer server components by default. Add “use client” only when necessary.
State Management
- Use Zustand for client-side global state.
- Avoid prop drilling beyond 2 levels; use context or state stores.
Accessibility
- All interactive elements must have aria labels.
Enforce semantic HTML (nav, main, section, article).
Backend Package Rules
# packages/backend/.cursorrules
## Framework
This package uses Node.js with Fastify and Prisma ORM.
## API Conventions
- All endpoints follow RESTful naming: plural nouns, no verbs.
- Use Zod schemas for request/response validation.
- Return consistent JSON envelope: { data, error, meta }.
## Database
- Never write raw SQL. Use Prisma client methods.
- All database calls must be wrapped in service layer functions.
- Use transactions for multi-table mutations.
## Security
- Sanitize all user inputs at the controller level.
- Use parameterized queries exclusively.
- Never log sensitive fields (password, token, ssn).
Step 4: Set Up Rules Syncing Across the Team
Commit all .cursorrules files to version control so every team member gets the same AI behavior.
# Ensure .cursorrules files are tracked
git add **/.cursorrules
git commit -m "chore: add cursor rules for monorepo code style enforcement"
git push origin main
Add a CI check to ensure rules files are not accidentally deleted or emptied:
# .github/workflows/check-cursorrules.yml
name: Validate Cursor Rules
on: [pull_request]
jobs:
check:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Verify root .cursorrules exists
run: |
if [ ! -s .cursorrules ]; then
echo "ERROR: Root .cursorrules is missing or empty"
exit 1
fi
- name: Verify package rules exist
run: |
for dir in packages/frontend packages/backend packages/shared; do
if [ ! -f "$dir/.cursorrules" ]; then
echo "WARNING: Missing .cursorrules in $dir"
fi
done
## Step 5: Use Project-Level Rules with .cursor/rules Directory (Cursor 0.45+)
Cursor versions 0.45 and above support a .cursor/rules/ directory with multiple rule files scoped by glob pattern. This offers even finer control:
monorepo/
└── .cursor/
└── rules/
├── global.mdc
├── react-components.mdc
└── api-routes.mdc
Each .mdc file uses frontmatter to define when it activates:
---
description: Rules for React components
globs: packages/frontend/src/components/**/*.tsx
alwaysApply: false
---
- Use React.FC type for all component definitions.
- Destructure props in the function signature.
- Place useEffect hooks after useState declarations.
Memoize expensive computations with useMemo.--- description: Rules for API route handlers globs: packages/backend/src/routes/**/*.ts alwaysApply: false
- Each route file exports a single Fastify plugin.
- Use the routeSchema object for input validation.
Return appropriate HTTP status codes (201 for creation, 204 for deletion).
Pro Tips for Power Users
- Layer rules intentionally: Place architectural decisions (folder structure, import conventions) at the root, and framework-specific patterns (React hooks order, API response shapes) at the package level.- Reference internal docs: Add lines like
Refer to docs/architecture.md for system design decisionsin your rules so Cursor can pull additional context.- Use negative rules: Explicitly stating what not to do is often more effective:Never use any as a type. Never use console.log in production code.- Version your rules: Add a comment like# v2.3 — Updated 2026-03-15at the top of each file to track changes over time.- Team onboarding: Include a section in your rules file titled## Onboarding Contextwith a brief description of the project’s purpose, stack, and key architectural decisions so new developers and the AI share the same mental model.- Combine with .cursorignore: Create a.cursorignorefile at the root to prevent Cursor from indexing build artifacts,node_modules, or generated files that could pollute AI suggestions.
Troubleshooting Common Issues
| Problem | Cause | Solution |
|---|---|---|
| Rules not applying to a package | File not named exactly .cursorrules | Check for typos. The filename is case-sensitive on Linux/macOS. |
| Child rules completely ignored | Cursor workspace root is set incorrectly | Open the monorepo root as the workspace in Cursor, not a subfolder. |
| AI generates code violating rules | Rules file too long or vague | Keep rules concise and specific. Aim for under 80 lines per file. Use imperative language. |
| Conflicting rules between packages | Overlapping glob patterns in .cursor/rules/ | Make glob patterns mutually exclusive. Use more specific paths. |
| Rules not picked up after editing | Cursor caches rules on workspace load | Reload the window: Ctrl+Shift+P → Developer: Reload Window. |
Can .cursorrules and .cursor/rules/ coexist in the same project?
Yes. The .cursorrules file at any directory level acts as a catch-all baseline, while .cursor/rules/*.mdc files activate based on glob patterns. When both apply to the same file, Cursor combines them. The .mdc rules supplement the .cursorrules content rather than replacing it. For clarity, many teams use .cursorrules for general project context and .cursor/rules/ for file-type-specific patterns.
How do I enforce that all team members actually use the Cursor Rules files?
Since .cursorrules files are committed to the repository, any team member using Cursor will automatically pick them up when they open the project. For enforcement beyond Cursor, pair your rules with traditional tooling: ESLint configs, Prettier, and CI checks that validate adherence. Add a CI step (as shown in Step 4) to verify that rules files exist and are non-empty. Include rules file review as part of your PR checklist.
Is there a maximum size or length limit for .cursorrules files?
There is no hard character limit, but practical effectiveness decreases with overly long files. Cursor includes the rules content in the AI’s context window, so extremely lengthy rules consume tokens that could be used for code context. Best practice is to keep each rules file under 80 lines and split concerns across the directory hierarchy or multiple .mdc files. Focused, actionable rules produce better AI output than exhaustive documentation.