The problem with one-size-fits-all rules
Most .cursorrules files treat every file in the project the same way. All the design tokens, all the coding conventions, all the architectural rules, dumped into one flat file. The AI reads all of it regardless of what it's working on.
When the AI is building a React component, the design token rules are essential. When it's writing an API route, those same rules are noise. They burn context window space, dilute the rules that actually matter for backend code, and sometimes cause the AI to inject UI-specific patterns where they don't belong.
Zone-based rules solve this by defining different constraints for different parts of your codebase. The AI gets exactly the rules it needs based on what file it's editing.
Defining your zones
A zone is a directory (or file pattern) with its own set of AI rules. Most projects naturally break into four zones:
Zone 1: Design system (maximum restriction)
Files in src/design/ and src/components/ui/. These are the foundation. The AI should almost never modify them. When it does, it needs explicit permission and must follow strict patterns.
# Zone 1: Design System — MAXIMUM RESTRICTION
# Applies to: src/design/*, src/components/ui/*
These files define the design system. Do not modify them
unless explicitly asked to change a design token or
primitive component.
If modifying:
- Every value must trace to a design token
- Changes propagate everywhere — be certain
- No new tokens without explicit approval
- Run a full component audit after changesZone 2: Feature UI (strict design enforcement)
Files in src/components/features/ and src/app/ that render UI. This is where most AI work happens. The design token rules apply fully. Color palettes, typography, spacing, radius, shadows. All enforced.
# Zone 2: Feature UI — STRICT DESIGN ENFORCEMENT
# Applies to: src/components/features/*, src/app/*/page.tsx
All UI code must reference the design system:
Colors: zinc palette only (never gray/slate/neutral)
bg: #FAFAFA | surface: #FFF | border: #E4E4E7
text: #18181B | muted: #71717A | primary: #6366F1
Typography: Inter (body 15px), Instrument Serif
(display), Geist Mono (code)
Radius: 8/12/16 only
Spacing: 4px base scale (4,8,12,16,24,32,48)
FORBIDDEN in this zone:
- Hardcoded hex values
- gray-*, slate-*, neutral-* color classes
- font-bold (use font-semibold)
- rounded-md (use rounded-lg/xl/2xl)
- Recreating existing ui/ components
REQUIRED:
- Import shared components from src/components/ui/
- Use CSS variables for all colors and spacing
- Mobile-first responsive designZone 3: Backend and API (type safety, no design rules)
Files in src/app/api/, src/lib/, and server-side utilities. Design tokens are irrelevant here. The constraints shift to type safety, error handling, and data validation.
# Zone 3: Backend/API — TYPE SAFETY ENFORCEMENT
# Applies to: src/app/api/*, src/lib/*, src/server/*
All API routes must:
- Use TypeScript strict types for request/response
- Validate input with zod or similar
- Return consistent error shapes:
{ error: string, status: number }
- Handle errors explicitly (no unhandled rejections)
Design rules DO NOT apply in this zone.
No color tokens, no typography, no spacing.Zone 4: Tests (minimal constraints)
Test files get the lightest touch. The AI should focus on coverage and correctness, not style.
# Zone 4: Tests — MINIMAL CONSTRAINTS
# Applies to: **/*.test.ts, **/*.test.tsx, **/*.spec.ts
Focus on:
- Test behavior, not implementation details
- Descriptive test names
- One assertion per test where practical
No design rules. No strict typing requirements.
Tests are allowed to use hardcoded values for assertions.How to implement zones in practice
The implementation depends on your AI tool. Here's how to handle it in the major agents:
Cursor: directory-level .cursorrules
Cursor supports .cursorrules files at any directory level. Place a zone-specific file in each major directory. The closest .cursorrules file wins.
src/
├── .cursorrules # Root: project-wide rules
├── components/
│ ├── ui/.cursorrules # Zone 1: design system protection
│ └── features/.cursorrules # Zone 2: design enforcement
├── app/
│ └── api/.cursorrules # Zone 3: backend rules
└── __tests__/.cursorrules # Zone 4: test rulesClaude Code: conditional sections in CLAUDE.md
Claude Code reads CLAUDE.md from the project root. You can't place multiple files in subdirectories, but you can structure the file with clear zone headers. The AI is smart enough to apply relevant sections based on what it's editing.
# CLAUDE.md — zone-based structure
## When editing UI files (components/features/*, app/*/page.tsx)
[full design token rules here]
## When editing API routes (app/api/*)
[backend rules here]
## When editing tests (**/*.test.*)
[minimal rules here]
## NEVER modify (protected zone)
- src/design/*
- src/components/ui/*Windsurf: .windsurfrules with context hints
Windsurf uses a single .windsurfrules file. Structure it the same way as CLAUDE.md with conditional sections. Windsurf's Cascade model applies the relevant section based on file context.
Why zones improve AI output quality
Zone-based rules don't just prevent drift. They actively improve the quality of what the AI generates. Here's why:
Less noise, better signal. When the AI is writing an API route and only sees backend rules, it focuses entirely on type safety and error handling. No cognitive overhead from design tokens it doesn't need. The rules that matter get the model's full attention.
Smaller context footprint. Zone-specific rules are shorter than global rules. Shorter rule files leave more context window for your actual code and conversation. This directly reduces the context decay problem where the AI starts ignoring rules as the conversation grows.
Clearer authority. When every file has one set of applicable rules (not a global rulebook where half the rules don't apply), the AI makes fewer judgment calls about which rules to follow. Fewer judgment calls means fewer regressions.
A real zone-based .cursorrules file
Here's what a complete root-level .cursorrules file looks like when it's zone-aware. This goes in your project root and provides the high-level architecture. The directory-level files handle the specifics.
# .cursorrules — Project Architecture
This project uses zone-based rules. The constraints
that apply to you depend on what file you're editing.
## Protected Zone (do not modify)
src/design/* and src/components/ui/*
These files are READ ONLY. Import them, don't edit them.
## UI Zone (strict design rules)
src/components/features/* and src/app/*/page.tsx
Full design system enforcement. See the .cursorrules
file in each directory for the complete token set.
## Backend Zone (type safety rules)
src/app/api/* and src/lib/*
No design rules. Strict TypeScript. Validated inputs.
## Test Zone (minimal rules)
**/*.test.* and **/*.spec.*
Focus on behavior, not style. Hardcoded values OK.SeedFlip's IDE rule file exports generate the Zone 2 content automatically. You get the full design token block, the forbidden values list, and the component import rules. Drop it into your features directory and the AI knows what your UI should look like.
When to use zones vs. a single file
Zone-based rules add complexity. They're not always worth it. Here's the decision framework:
Use zones when your project has both frontend and backend code, when you have more than 50 components, or when multiple AI agents work on the same codebase. The complexity pays for itself in consistency.
Use a single file when your project is small (under 20 components), purely frontend, or when you're the only person (or agent) working on it. A well-written single file handles this scale fine.
Zone-based rules are the advanced pattern for teams and projects that outgrow a single rules file. They match the constraint to the context, reduce context noise, and let the AI focus on what matters for each file type. To get started with the design enforcement zone, read How .cursorrules Shape AI Design Output. For the token layer that powers it, see From Design Tokens to IDE Rule Files.