Skip to content

Project vs User Instructions

Three layers — global user, project, and project-local. The hierarchy, override behavior, and when to use each one.

You have one CLAUDE.md in your project root. Works fine. Then you start a second project and realize you want some of the same rules everywhere. Copy-paste them? No. Claude Code has a layered system for exactly this.

The Four Layers

Think CSS specificity. More specific wins.

ScopeLocationWho sees it
Managed policyOS-level paths (set by your org)Everyone in the org
Project./CLAUDE.md or ./.claude/CLAUDE.mdYour whole team (checked into git)
User~/.claude/CLAUDE.mdJust you, across all projects
Local./CLAUDE.local.mdJust you, in this project only

Managed policy is the top layer. Your company sets it, you can't exclude it. Most individual developers never touch this. Move on.

Project is the team layer. Committed to source control. Everyone who clones the repo gets the same rules. Coding standards, build commands, architecture decisions.

User is personal. You prefer a certain response style, or you always want confidence scores. Put that in ~/.claude/CLAUDE.md and it follows you to every project you open.

Local is the most specific and the most underused. Same project, your personal twist. Different environment paths, different test commands than your teammate. Stays out of git.

If your project CLAUDE.md says "use tabs" and your local file says "use spaces," spaces win for you. Simple.

How Loading Actually Works

Claude Code doesn't just read one file. It walks up the directory tree from your current working directory.

Say your repo looks like this and you run Claude Code from foo/bar/:

my-repo/
  CLAUDE.md          # loaded second
  foo/
    CLAUDE.md        # loaded first (closer to CWD)
    bar/
      CLAUDE.md      # loaded first (this is CWD)

All three files get loaded. Closest to CWD gets highest priority. Files in subdirectories below your CWD only load on demand, when Claude starts working with files down there.

Monorepos benefit from this heavily. Each package can have its own CLAUDE.md with package-specific instructions, and they only kick in when relevant. No wasted context on rules for packages you aren't touching.

The Rules Directory

Single CLAUDE.md files get janky fast once your project has enough conventions to track. The .claude/rules/ directory is the better approach. Drop individual .md files in there, each covering one topic:

.claude/
  rules/
    testing.md
    api-standards.md
    frontend/
      react-patterns.md
      styling.md
    backend/
      database.md

All .md files get discovered recursively. Organize subdirectories however you want. By default, every rule file loads at launch with the same priority as your project CLAUDE.md.

The real power move: path-specific rules using YAML frontmatter:

---
paths:
  - "src/api/**/*.ts"
---
# API Development Rules
- All API endpoints must include input validation
- Return consistent error shapes
- Log every mutation

This rule only activates when Claude Code works with files matching that glob. Your API rules stay out of the context window when you're editing React components. Free context you didn't have to think about.

Glob patterns work how you'd expect. **/*.ts matches all TypeScript files. src/**/* matches everything under src. Brace expansion works too: src/**/*.{ts,tsx}.

Your user-level rules directory (~/.claude/rules/) works identically but loads before project rules, applying to every project.

One trick worth knowing: symlinks work in .claude/rules/. Multiple projects sharing the same testing standards? Symlink to a single source of truth instead of duplicating.

Try It: Set Up Your Own Layers

Create a user-level CLAUDE.md if you don't have one:

mkdir -p ~/.claude
cat > ~/.claude/CLAUDE.md << 'EOF'
# My Global Preferences
- Always explain your reasoning before writing code
- Use descriptive variable names
EOF

Now a path-specific rule:

mkdir -p .claude/rules
cat > .claude/rules/tests.md << 'EOF'
---
paths:
  - "**/*.test.ts"
  - "**/*.spec.ts"
---
# Testing Rules
- Use descriptive test names that explain the expected behavior
- One assertion per test when possible
EOF

Run Claude Code and ask it to write a test file. Then ask it to write a regular source file. Watch how the testing rules only appear when relevant.

Monorepo Patterns

In a monorepo, you probably don't want every team's CLAUDE.md clogging up your context. Use claudeMdExcludes in .claude/settings.local.json:

{
  "claudeMdExcludes": [
    "**/monorepo/CLAUDE.md",
    "/home/user/monorepo/other-team/.claude/rules/**"
  ]
}

For CLAUDE.local.md, remember it isn't checked into git. If you use git worktrees, you lose your local instructions in each new worktree. The fix: put personal project preferences in your home directory and import them:

# Individual Preferences
- @~/.claude/my-project-instructions.md

That @ syntax pulls in the referenced file. Works from any worktree.

One Caveat

CLAUDE.md files are context, not enforced configuration. No runtime validation. Conflicting instructions across files? Claude Code picks one. No error, no warning. You just get inconsistent behavior and wonder why.

Review your instruction files periodically. Check for contradictions between layers, and don't repeat yourself across scopes.

What Matters

  • Four layers, more specific wins. Managed policy, project, user, local.
  • Claude Code walks the entire directory tree, loading every CLAUDE.md it finds between CWD and repo root.
  • .claude/rules/ with path-specific YAML frontmatter is the cleanest way to organize conventions without bloating context.
  • CLAUDE.local.md stays out of git. Your personal escape hatch.
  • Conflicting instructions fail silently. Audit periodically.

Mastering Claude Code

Lesson 10 of 70