CLAUDE.md is a plain Markdown file at the project root that Claude Code automatically reads at the start of every conversation. It provides persistent project context — architectural decisions, coding conventions, and contextual knowledge — without repeating them in every prompt.
How Claude Code Finds CLAUDE.md
Claude reads CLAUDE.md files from multiple locations, and they stack:
- Global:
~/.claude/CLAUDE.md— instructions that apply across all your projects (personal preferences, formatting standards, etc.) - Project root:
CLAUDE.md— shared team conventions, committed to git - Personal override:
CLAUDE.local.md— gitignored, for individual preferences that shouldn’t affect teammates - Child directories: CLAUDE.md files in subdirectories load on-demand when Claude works in that part of the monorepo
For a dbt project, the project root file is where most of the value lives. It’s what your whole team shares.
The Instruction Budget
Here’s the constraint most people miss: frontier LLMs can reliably follow approximately 150-200 instructions at once. Claude Code’s system prompt already contains around 50, which leaves limited capacity for your custom instructions. Stuffing every possible command, convention, and edge case into CLAUDE.md doesn’t make Claude smarter — it makes Claude worse at following any single instruction.
This means CLAUDE.md should be curated, not comprehensive. Include what’s universally applicable to every conversation. Reference separate files for detailed documentation rather than inlining it. Use pointers instead of copying code snippets, because snippets become outdated quickly and waste instruction budget on content Claude could discover by reading the actual file.
What Belongs in CLAUDE.md
For a dbt/BigQuery project, effective CLAUDE.md entries typically cover:
- Naming conventions: Model prefixes (
base__,int__,mrt__), the double-underscore separator, singular entity names. Without this, Claude defaults to community conventions that might not match yours —stg_instead ofbase__, for example. - Project structure: Where models live, how folders are organized, which schema maps to which layer. See dbt Project Structure and Naming for the conventions worth encoding.
- Testing requirements: Minimum test expectations (unique + not_null on every primary key), preferred test packages, severity conventions.
- SQL style: Dialect-specific patterns (BigQuery’s backtick quoting,
SAFE_DIVIDE,PARSE_DATEformats), CTE naming conventions, join style preferences. - What NOT to do: Explicit prohibitions are often more valuable than positive instructions. “Never use
SELECT *in models.” “Never modify files inmodels/marts/prod/without confirmation.” “Never useCURRENT_TIMESTAMP()without timezone handling.”
What Doesn’t Belong
- Generic SQL knowledge Claude already knows. Don’t explain what a LEFT JOIN is.
- Full code examples that duplicate files in your repo. Point to the file instead: “See
macros/generate_schema_name.sqlfor our custom schema naming logic.” - Instructions for rare edge cases that come up once a quarter. Handle those in-conversation when they arise.
- Auto-generated content from
/init. Claude Code’s/initcommand produces a CLAUDE.md by scanning your project, but the output tends to be generic — things Claude would discover on its own by reading your code. It’s a starting point at best, not a finished product.
The Reactive Approach
The best CLAUDE.md files are built reactively, not proactively. Start with a blank file. Work with Claude Code for a few sessions. When Claude repeatedly gets something wrong — uses stg_ instead of base__, creates models in the wrong directory, forgets to add primary key tests — add a one-line instruction to CLAUDE.md addressing that specific mistake.
This approach has two advantages. First, every instruction earns its place by solving a real problem. Second, you avoid the trap of speculative instructions that sound useful but consume instruction budget without preventing actual errors.
Over a few weeks, a CLAUDE.md built this way converges on the 20-30 instructions that genuinely matter for your project. That’s a much better use of the instruction budget than a 200-line document written on day one.
A Practical Example
A mature CLAUDE.md for a dbt/BigQuery project might look something like:
# Project: analytics-warehouse
## Models- Use `base__`, `int__`, `mrt__` prefixes (not stg/dim/fct)- Double underscore separates prefix, source/domain, and entity- Singular entity names: `customer` not `customers`- All models in `models/{base,intermediate,marts}/`
## SQL- BigQuery dialect: backtick-quote dataset references- Always use SAFE_DIVIDE for division- CTEs named descriptively, not `cte1`, `cte2`- No SELECT * in any model
## Testing- Every primary key: unique + not_null- Every foreign key: relationships test- Run dbt build --select <model>+ after changes
## Don't- Never modify models/marts/prod/ without asking- Never use CURRENT_TIMESTAMP without TIMESTAMP_TRUNC- Never create ephemeral modelsNotice how short this is. Each line addresses a specific, recurring mistake. No explanations, no examples, no redundancy. Claude reads it in seconds and carries it through the entire conversation.
Relationship to Hooks and Commands
CLAUDE.md provides guidance — Claude should follow it, but it’s not enforced. For rules that must never be broken (like blocking edits to production schemas), use Claude Code Hooks instead. For repeatable multi-step workflows (like generating tests or documentation), use Claude Code Slash Commands for dbt. CLAUDE.md, hooks, and commands form three layers of project configuration: context, guardrails, and automation.