What you will be able to do
- Explain what a .claude/rules/ file is and how it differs from CLAUDE.md
- Write a rule file whose YAML paths frontmatter gates it to matching files
- Choose glob patterns that target files by type anywhere in the tree, or by location
- Choose a path-scoped rule over per-directory CLAUDE.md files when one convention applies to files scattered across many directories
Key concept
Path-gated rule — A markdown file in .claude/rules/ that holds instructions on one topic. If its YAML frontmatter has a paths field, Claude Code loads it only when Claude works with a file that matches one of the listed glob patterns, not in every session.
1.From one CLAUDE.md to a rules directory
Your project CLAUDE.md loads in every session. That's what you want for build commands and conventions that apply everywhere. It's wasteful for guidance that only matters when Claude touches one kind of file, such as API handler rules, testing conventions or infrastructure-as-code standards. If all of that sits in one file, Claude carries every instruction into every conversation, even when it's editing a README.
The .claude/rules/ directory lets you split instructions into topic files. Each rules/*.md file is committed with the project like CLAUDE.md, and the same mechanism also exists at the global level. The documentation shows a project where the main CLAUDE.md sits next to a rules/ folder holding separate files for code style, testing and security.
your-project/
├── .claude/
│ ├── CLAUDE.md # Main project instructions
│ └── rules/
│ ├── code-style.md # Code style guidelines
│ ├── testing.md # Testing conventions
│ └── security.md # Security requirementsSplitting files alone doesn't change what lands in context. A rule file with no frontmatter loads every session, just like CLAUDE.md. The difference comes from the optional paths field, covered in the next section. The features overview places rules between CLAUDE.md, which is always on, and skills, which load on demand:
| Aspect | CLAUDE.md | .claude/rules/ | Skill |
|---|---|---|---|
| Loads | Every session | Every session, or when matching files are opened | On demand, when invoked or relevant |
| Scope | Whole project | Can be scoped to file paths | Task-specific |
| Best for | Core conventions and build commands | Language-specific or directory-specific guidelines | Reference material, repeatable workflows |
Checkpoint 1 of 4· Check yourself
A team moves its testing conventions out of CLAUDE.md into .claude/rules/testing.md and adds no frontmatter. When does that file load?
Without paths, a rule isn't gated. It loads every session. Only a paths field makes it load conditionally.
“Every session, or when matching files are opened”Source: code.claude.com
2.Scoping a rule with paths frontmatter
To make a rule conditional, start the file with a YAML frontmatter block that contains paths. According to the .claude directory reference, paths is the only frontmatter field a rule file takes. Its value is a set of glob patterns. The rule applies only to files that match one of them. The memory documentation's example limits API rules to TypeScript files under src/api/:
---
paths:
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation commentsThe field is optional. It accepts glob patterns that scope the rule to matching files, written as a YAML list, as shown above, or as a single comma-separated string. Everything after the closing --- is ordinary markdown, so the body can use the same headers and bullets you'd use in CLAUDE.md. The same pattern works for any area of the codebase. For infrastructure conventions, for example, you could gate a rule on everything under a terraform/ directory with a pattern of the src/**/* form, such as terraform/**/*. Then Terraform guidance enters context only when Claude is working on Terraform files.
Glob-pattern rules also have an advantage over directory-level CLAUDE.md files. A CLAUDE.md lives inside one directory and loads when Claude starts there or reads a file there, so its conventions follow a folder. Many conventions follow a file type instead. Test files, for example, sit beside the code they test in many different directories. Covering them with directory CLAUDE.md files would mean a copy in every one of those directories. A single path-scoped rule in the central .claude/rules/ folder, with a pattern like **/*.test.tsx, loads whenever Claude works with a matching file, wherever it lives. Choose per-directory CLAUDE.md when the directory's owners maintain their own conventions, and a path-scoped rule when the same rule applies to scattered paths.
| Approach | File location | Loads when | Use when |
|---|---|---|---|
| Per-directory CLAUDE.md | Inside the directory, alongside its code | At launch when started from that directory, or on demand when Claude reads a file there | Directory owners maintain their own conventions; instructions are versioned with the code |
| Path-scoped rule in .claude/rules/ | Central .claude/ at the repo root | When Claude works with a file matching the rule’s paths: glob | You want all conventions in one place, or the same rule applies to many scattered paths |
Checkpoint 2 of 4· Fill the gap
Which frontmatter key makes this rule conditional?
---
? :
- "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Use the standard error response format
- Include OpenAPI documentation commentsRule files support a single frontmatter field, paths, which holds the glob patterns that scope the rule.
Source: code.claude.com3.Glob patterns: matching by type or by location
Which pattern you write decides whether a rule follows a file type or a location. A leading **/ matches at any depth, so **/*.ts covers TypeScript files wherever they live. A directory prefix fixes the location: src/**/* covers everything below src/, and src/components/*.tsx covers only the components in that one folder. A bare *.md stays at the project root.
| Pattern | Matches |
|---|---|
| **/*.ts | All TypeScript files in any directory |
| src/**/* | All files under src/ directory |
| *.md | Markdown files in the project root |
| src/components/*.tsx | React components in a specific directory |
Type-based matching is what makes rules useful for conventions that don't follow your folder layout. Test files are the classic case, because they usually sit next to the code they test, all over the tree. Use the same form as **/*.ts, the any-depth wildcard plus a filename suffix, and write **/*.test.tsx. That one pattern then reaches every React test file in any directory.
One rule can list several patterns, and brace expansion lets one pattern cover more than one extension. The documentation's multi-pattern example combines a brace pattern, a second directory and a test-file suffix:
---
paths:
- "src/**/*.{ts,tsx}"
- "lib/**/*.ts"
- "tests/**/*.test.ts"
---Checkpoint 3 of 4· Check yourself
A testing rule must apply to every .ts file in the repository, including files scattered across many unrelated folders. Which paths entry does that with a single pattern?
The leading **/ matches any directory depth, so the pattern follows the file type rather than one location. *.ts stays at the root, and the other two options are tied to a single directory.
“All TypeScript files in any directory”Source: code.claude.com
Checkpoint 4 of 4· Exam question
A platform engineer maintains a monorepo where test files (matching *.test.ts) are scattered across src/, lib/, packages/*/tests/, and e2e/ directories. The engineer wants testing conventions to load automatically whenever Claude works on any test file, without duplicating the same instructions across multiple subdirectory CLAUDE.md files. Which approach best achieves this?
Correct answer: A — Create a single .claude/rules/testing.md file with paths: ["**/*.test.ts"] in its YAML frontmatter, so the rule loads whenever Claude reads a file matching that pattern anywhere in the repo.
- A. Correct. A single rules file scoped with a recursive glob pattern in the paths frontmatter applies by file type regardless of directory, and loads only when a matching file is opened, avoiding duplication and reducing irrelevant context.
- B. Duplicating a CLAUDE.md per directory means every new test directory needs its own copy, and edits must be kept in sync manually across all copies, which is exactly the maintenance burden path-specific rules avoid.
- C. Placing the conventions in the root CLAUDE.md loads them into every session regardless of whether Claude is touching test files, consuming context on unrelated work instead of loading conditionally.
- D. claudeMdExcludes is used to skip loading specific CLAUDE.md or rules files by path; it does not cause conditional loading of guidance and does not scope a rule to a file-type pattern.
Sources3
Exam traps
Each one states something that sounds right. Open it to see what is actually true.
1.Any file placed in .claude/rules/ loads only when relevant files are opened.Why is that wrong?
Conditional loading needs a paths field. Rules without one load every session, and after compaction they're re-injected along with the project-root CLAUDE.md.
Covered in From one CLAUDE.md to a rules directory
2.To apply test-file conventions across a codebase, put a CLAUDE.md in every directory that contains tests.Why is that wrong?
A directory CLAUDE.md follows a folder, so scattered test files would need many copies. One path-scoped rule with a glob such as **/*.test.tsx covers them all from a single central file.
Covered in Scoping a rule with paths frontmatter
3.A pattern like *.md or src/components/*.tsx matches files at any depth.Why is that wrong?
Only a ** segment crosses directory levels. *.md matches Markdown files in the project root only, and **/*.ts is the form that matches a type anywhere.
Sources
Every claim above is drawn from one of these pages, quoted as it was written on the date shown.
- 1.https://code.claude.com/docs/en/features-overviewOfficial docs
“Language-specific or directory-specific guidelines”
↩︎ From one CLAUDE.md to a rules directory“Every session, or when matching files are opened”
↩︎ Checkpoint - 2.https://code.claude.com/docs/en/claude-directoryOfficial docs
“Topic-scoped instructions, optionally path-gated”
↩︎ From one CLAUDE.md to a rules directory“Topic-scoped instructions, optionally path-gated”
↩︎ Key concept - 3.https://code.claude.com/docs/en/memoryOfficial docs
“Glob patterns that scope the rule to matching files. Accepts a YAML list or a comma-separated string”
↩︎ Scoping a rule with paths frontmatter“All TypeScript files in any directory”
↩︎ Glob patterns: matching by type or by location“Markdown files in the project root”
↩︎ Exam trap 3“Markdown files in the project root”
↩︎ Prediction - 4.https://code.claude.com/docs/en/large-codebasesOfficial docs
“You want all conventions in one place, or the same rule applies to many scattered paths”
↩︎ Scoping a rule with paths frontmatter“the same rule applies to many scattered paths”
↩︎ Exam trap 2
Also cited
- https://code.claude.com/docs/en/context-windowOfficial docs
“Project-root CLAUDE.md and unscoped rules”
↩︎ Exam trap 1