Skip to content

How Do I Use .claude/rules for Project-Specific Configuration in Claude Code?

I was working on a monorepo with TypeScript frontend, Go backend, and Python scripts. Every time I asked Claude to help with a Go file, it kept suggesting TypeScript-style conventions. Frustrating.

What I kept seeing
# In my Go file...
type User struct { // Claude suggests: "Consider using interface"
ID string
Name string
}

The problem? My .claude/rules/coding-style.md was loading for every file, regardless of language.

The Solution: YAML Frontmatter with Paths

Claude Code supports conditional rule loading through YAML frontmatter. Add a paths array to scope rules to specific file patterns:

.claude/rules/typescript.md
---
paths:
- "**/*.ts"
- "**/*.tsx"
---
# TypeScript Conventions
Prefer interfaces over types for object shapes:
```typescript
interface User {
id: string
name: string
}
Now this rule only loads when Claude reads `.ts` or `.tsx` files.
## How Paths Work
The `paths` array uses glob patterns:
```text title="Pattern matching explained"
*.ts → Matches only root-level .ts files
**/*.ts → Matches .ts files in any directory
src/**/*.ts → Matches .ts files under src/
**/api/**/*.ts → Matches .ts files in any api/ directory

What I Changed

I split my single coding-style.md into language-specific files:

.claude/rules/
├── typescript.md # paths: ["**/*.ts", "**/*.tsx"]
├── go.md # paths: ["**/*.go"]
├── python.md # paths: ["**/*.py"]
└── react.md # paths: ["**/components/**/*.tsx"]

Each file has its own paths frontmatter.

Example: Go-Specific Rules

.claude/rules/go.md
---
paths:
- "**/*.go"
---
# Go Conventions
## Naming
- Exported: PascalCase
- Unexported: camelCase
- Acronyms: HTTP, URL, ID (not Http, Url, Id)
## Error Handling
Always check errors:
```go
result, err := someFunction()
if err != nil {
return fmt.Errorf("operation failed: %w", err)
}
## Example: Test File Rules
```yaml title=".claude/rules/testing.md"
---
paths:
- "**/*.test.ts"
- "**/*.spec.ts"
- "**/__tests__/**/*.ts"
---
# Testing Conventions
- AAA pattern: Arrange, Act, Assert
- Target 80%+ coverage
- Test edge cases and error paths

Why This Matters

  1. Context efficiency: Rules load only when relevant
  2. No conflicts: TypeScript rules won’t interfere with Go work
  3. Clarity: Each file type gets focused conventions
  4. Maintainability: Easier to manage per-language rules

Common Mistakes I Made

Mistake 1: Forgot the triple dashes

WRONG - Missing delimiters
paths:
- "**/*.ts"
---
# Rules here...
CORRECT - Proper frontmatter
---
paths:
- "**/*.ts"
---
# Rules here...

Mistake 2: Wrong glob pattern

Pattern comparison
*.ts → Only matches /root/file.ts
**/*.ts → Matches /any/path/file.ts

Mistake 3: Contradictory rules in overlapping paths

If two rule files both match app.ts, both load. Keep rules consistent.

Visualizing Rule Loading

How Claude Code loads rules
┌─────────────────┐
│ Claude reads │
│ src/api/user.ts │
└────────┬────────┘
┌─────────────────────────────┐
│ Check .claude/rules/*.md │
│ │
│ typescript.md │
│ paths: ["**/*.ts"] │
│ → MATCHES ✓ (loads) │
│ │
│ go.md │
│ paths: ["**/*.go"] │
│ → NO MATCH (skips) │
│ │
│ api.md │
│ paths: ["**/api/**/*.ts"] │
│ → MATCHES ✓ (loads) │
└─────────────────────────────┘
┌─────────────────────────────┐
│ TypeScript + API rules │
│ applied to user.ts │
└─────────────────────────────┘

Multiple Path Patterns

You can combine patterns in one file:

.claude/rules/config.md
---
paths:
- "*.config.js"
- "*.config.ts"
- "**/webpack.*.js"
- "**/vite.config.*"
---
# Configuration File Rules
- Use commonjs for webpack configs
- Use ES modules for vite configs
- Never hardcode secrets

Directory-Specific Rules

Scope rules to specific directories:

.claude/rules/migrations.md
---
paths:
- "**/migrations/**/*.sql"
---
# Database Migration Rules
- Naming: YYYYMMDDHHMMSS_description.sql
- Always include up and down
- Never modify existing migrations

Summary

YAML frontmatter with paths gives you fine-grained control over when rules load. Start with broad patterns for language conventions, then add specific paths for framework or directory rules.

Key takeaways:

  • Use **/*.ext for recursive matching
  • Group related rules in single files
  • Keep rules concise (they consume context)
  • Test that patterns match expected files

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments