Rules are standalone instruction files that Claude Code loads automatically alongside your CLAUDE.md. Instead of stuffing everything into one massive file, you split instructions by topic. Each rule file targets specific concerns and can even be scoped to specific file types.
I use rules to enforce coding standards that I don’t want to repeat every session. Things like “don’t add obvious comments” or “don’t add type annotations TypeScript can infer” are exactly the kind of instructions that belong in rules.
1. How rules work
a. File location
Rules live in a rules/ directory, either at user-level or project-level:
| Location | Scope |
|---|---|
~/.claude/rules/*.md | User-level, applies to all your projects |
.claude/rules/*.md | Project-level, shared via version control |
All .md files in these directories are discovered recursively, so you can organize with subdirectories too.
b. Loading behavior
- Rules without frontmatter load unconditionally on every session
- Rules with
pathsfrontmatter only load when Claude works with matching files - User-level rules load before project rules (project rules take higher priority)
c. Frontmatter fields
| Field | Description |
|---|---|
paths | Glob patterns for when to apply this rule |
description | Short description of what the rule covers |
alwaysApply | When true, load regardless of file context |
2. My rules
a. Anti-slop
This is the rule I’m most glad I wrote. Without it, Claude Code tends to over-engineer: adding type annotations TypeScript can already infer, wrapping everything in try/catch, creating abstractions for one-time operations.
---
paths:
- "**/*.ts"
- "**/*.tsx"
- "**/*.js"
- "**/*.jsx"
- "**/*.py"
- "**/*.go"
- "**/*.rs"
alwaysApply: true
description: Anti-slop coding rules
---
## Anti-Slop Rules
### Do NOT
- Add type annotations TypeScript can infer
- Add error handling for impossible cases
- Create abstractions/helpers for one-time operations
- Add logging/console.log unless asked
- Add TODO/FIXME/HACK comments
- Introduce new patterns when codebase already has one
- Add default values that are never used
- Add unnecessary try/catch blocks
- Over-validate internal function inputs
- Add fallback values "just in case"
### Do
- Match existing codebase style and patterns
- Prefer early return over else blocks
- Prefer flat code over deep nesting
- Keep functions short and single-purpose
- Delete dead code, don't comment it out
- Use existing utilities before creating new ones I built the “Do NOT” list from real annoyances. Every item is something Claude Code kept doing until I explicitly told it to stop.
b. Comment policy
This rule pairs well with anti-slop. Claude Code loves to add comments explaining what code does, which is almost always unnecessary if the code is written clearly.
---
paths:
- "**/*.ts"
- "**/*.tsx"
- "**/*.js"
- "**/*.jsx"
- "**/*.py"
alwaysApply: true
description: Comment policy
---
## Comment Policy
### Unacceptable Comments
- Comments that repeat what code does
- Commented-out code (delete it)
- Obvious comments ("increment counter")
- Comments instead of good naming
### Principle
Code should be self-documenting. If you need a comment
to explain WHAT the code does, consider refactoring to
make it clearer. The principle at the bottom is important. It’s not “never comment”, it’s “if you need a comment to explain what the code does, the code itself should be clearer.”
3. Path-specific rules
One of the most useful features of rules is scoping them to specific paths. This means you can have different standards for different parts of your codebase.
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation comments This rule only applies when Claude is working with files in src/api/. Supported glob patterns:
| Pattern | Matches |
|---|---|
**/*.ts | All TypeScript files in any directory |
src/**/* | All files under src/ |
src/components/*.tsx | React components in a specific directory |
src/**/*.{ts,tsx} | Both .ts and .tsx files under src/ |
4. Writing your own rules
a. Start from pain points
Don’t try to write rules preemptively. Wait until Claude Code does something that annoys you, then add a rule to prevent it. My anti-slop rule grew one item at a time over weeks.
b. Be specific
“Write good code” is useless. “Prefer early return over else blocks” is actionable. Rules should be concrete enough that you could objectively check whether the output follows them.
c. Organize by topic
~/.claude/rules/
├── anti-slop.md # Code quality standards
├── comments.md # Comment policy
├── testing.md # Test conventions
└── security.md # Security requirements Each file covers one concern. This makes rules easy to find, update, and share.
d. Use alwaysApply carefully
Setting alwaysApply: true means the rule loads on every session regardless of what files you’re working with. This is fine for broad coding standards (like anti-slop), but wasteful for rules that only apply to specific file types. Use paths for targeted rules.
5. Rules vs CLAUDE.md
Both instruct Claude Code, but they serve different purposes:
| CLAUDE.md | Rules | |
|---|---|---|
| Content | Project overview, commands, architecture | Specific coding standards, conventions |
| Granularity | One file per scope | One file per topic |
| Scoping | Directory-based | Path glob patterns |
| Best for | “What is this project” | “How to write code in this project” |
A good setup uses CLAUDE.md for project context (stack, commands, structure) and rules for coding standards (style, conventions, constraints).