When a path-scoped rule loads
- Session startsonly unscoped rules and CLAUDE.md load
- Claude reads a filee.g.
src/api/users.ts - Glob checkdoes it match any rule’s
paths? - Rule joins context
api.mdconventions now apply
paths load at launch like the project CLAUDE.md. Rules with paths wait until Claude reads a file that matches one of their globs.What a rule file is
Rules are Markdown files in a project’s .claude/rules/ directory, one topic per file with a descriptive name such as testing.md or api-design.md. Files are discovered recursively, so you can group them in folders like frontend/ and backend/. They are committed with the repository, so the whole team gets them.
A rule with no frontmatter loads at session start with the same priority as .claude/CLAUDE.md — it is simply a way to split a long CLAUDE.md into topic files. Add a paths field in YAML frontmatter and the rule becomes conditional: it loads only when Claude works with files that match one of its glob patterns.
---
paths:
- "src/api/**/*.ts"
---
# API development rules
- Validate every request body with the shared zod schemas
- Return errors in the standard { code, message } shape
- Add an OpenAPI comment to each new endpointWriting the globs
The paths value is a list of glob patterns. ** matches any number of directories, * matches within one path segment, and braces expand to alternatives. Quote each pattern in the YAML. You can list several patterns in one rule, and a brace group such as {ts,tsx} covers several extensions in one line.
| Pattern | Matches |
|---|---|
**/*.ts | Every TypeScript file, in any directory |
src/**/* | Everything under src/ |
*.md | Markdown files in the project root only |
src/components/*.tsx | Components directly in that folder, not in subfolders |
src/**/*.{ts,tsx} | TypeScript and TSX anywhere under src/ |
**/*.test.ts | Every test file, wherever it lives |
Checking files against paths: ["src/api/**/*.ts"]
- Passes:
src/api/users.ts**can match zero folders - Passes:
src/api/v2/billing/invoices.tsany depth undersrc/api/ - Fails:
src/api/users.test.tsx.tsxis not.ts - Fails:
lib/api/users.tswrong top-level folder - Fails:
src/apis/users.tsapisis notapi
** crosses any number of folders, but the pattern still needs the src/api/ prefix and the .ts extension.Rules or per-directory CLAUDE.md?
Both target part of the tree, and both load on demand. The difference is where the file lives and what it can match. A subdirectory CLAUDE.md can only describe files inside its own folder. A rule lives centrally in .claude/rules/ and can match any glob — including files scattered all over the codebase.
Two ways to scope a convention
Per-directory CLAUDE.md
- Lives beside the code, e.g.
packages/api/CLAUDE.md - Covers only files inside that folder
- Loads when Claude reads a file there, or at launch if started there
- Good when a folder’s owners maintain their own conventions
Path-scoped rule
- Lives centrally in
.claude/rules/ - Matches any glob, e.g.
**/*.test.ts - Loads when Claude reads a matching file
- Good for conventions that cut across folders
Personal, shared and debugging
- User-level rules.
~/.claude/rules/applies to every project on your machine. These load before project rules, so project rules take priority. - Sharing across repositories.
.claude/rules/supports symlinks to a shared folder. A link that points outside the working directory is treated like an external import and needs approval — and even then, only its rules withoutpathsload. - Excluding.
claudeMdExcludesin settings can skip another team’s rules directory by glob, just as it skips their CLAUDE.md files (see 3.1). - Skills can be path-scoped too. A skill’s
pathsfrontmatter makes Claude load it automatically only for matching files — useful when the guidance is a procedure rather than a short rule (see 3.2). - Debugging.
/contextlists loaded rules under Memory files. TheInstructionsLoadedhook fires whenever a CLAUDE.md or rule file loads, with aload_reasonsuch aspath_glob_match; it is informational and cannot block loading.
Where should this convention go?
- Every file, every sessionRoot
CLAUDE.mdor an unscoped rule - Files in one folderFolder CLAUDE.mdor a rule scoped to that folder
- A pattern across foldersPath-scoped rulee.g.
**/*.test.ts - A long procedureSkilloptionally with
paths
Traps the wrong answers are built from
| Tempting but wrong | Do this instead |
|---|---|
| Putting file-type conventions in the root CLAUDE.md | Move them into .claude/rules/ with paths so they load only for matching files. |
| Copying the same CLAUDE.md into every folder that has tests | Write one rule scoped with a glob such as **/*.test.ts. |
Splitting CLAUDE.md into rule files without paths and expecting context savings | Unscoped rules load at launch like CLAUDE.md; add paths to make them conditional. |
Writing src/api/*.ts when handlers live in nested folders | Use ** (e.g. src/api/**/*.ts) to match any depth. |
| Putting a hard guarantee in a path-scoped rule | Rules are guidance like CLAUDE.md; use hooks or permission rules to enforce. |
You should now be able to
- Create a rule in
.claude/rules/and scope it withpathsfrontmatter. - Write glob patterns that match exactly the intended files, including
**and brace groups. - Explain that scoped rules load when Claude reads a matching file, and unscoped rules load at launch.
- Choose between a path-scoped rule, a per-directory CLAUDE.md and a skill for a given convention.
- Confirm a rule loaded with
/contextor theInstructionsLoadedhook.