The Markdown Files That Power Claude Code:
A Developer's Complete Guide
Every .md file in Claude Code's ecosystem — what it does, how it loads, and how to write it well.
Claude Code uses markdown files as its primary configuration, memory, and extensibility layer. Unlike tools that rely on JSON configs or database records, Claude Code turns plain markdown into first-class citizens of the developer experience.
The mental model is layered:
🔵 Universal LoadCLAUDE.md files always load in their scope — every conversation, every session
🟢 Conditional LoadSKILL.md bodies load when a skill triggers or is invoked by the user
🟡 On-Demand Loadreferences/ files load only when the skill body explicitly directs Claude to them
Memory files accumulate knowledge that outlasts individual conversations
🔴 Session-ScopedPlan files capture pre-execution architecture for a specific task
⚙️ CI/CD NoteCLAUDE_CODE_SIMPLE=true disables all context loading — CLAUDE.md, skills, memory, agents, hooks, and MCP tools. Use this in automated pipelines for predictable behavior.
Part 1
CLAUDE.md — The Project Brain
What CLAUDE.md Does
CLAUDE.md is injected into every conversation in its scope. It is the primary mechanism for giving Claude persistent, session-to-session knowledge about your codebase. It competes with the codebase for context window space — density beats verbosity.
The Four Tiers of CLAUDE.md
| Level | Path | Git-tracked? | Scope |
|---|---|---|---|
| Global | ~/.claude/CLAUDE.md | No (personal) | Every project on your machine |
| Project root | {project}/CLAUDE.md | Yes | All conversations in the project |
| Subdirectory | {project}/src/CLAUDE.md | Yes | Conversations scoped to that directory |
| Local override | {project}/.claude.local.md | No — must gitignore | Personal, machine-specific |
Additive Loading in Monorepos
Loading is additive, not replacing. Claude concatenates global + project root + subdirectory CLAUDE.md files. Subdirectory files should only add scope-specific context — never repeat what is already in a parent file.
What Belongs in CLAUDE.md
- Commands —
npm run dev,npm run build, deploy commands, test runners - Architecture — directory structure, provider hierarchy, key entry points
- Non-obvious patterns — "Two data-fetching patterns coexist; prefer TanStack Query for new code"
- Gotchas — "Dev server runs on port 8080. Kill old processes on 8080–8082 before starting."
- Code style conventions — path aliases, utility imports, TypeScript settings
- Deployment — hosting provider, backend, domain, config file locations
Context Window Budget
💡 Budget Guidelines- CLAUDE.md all levels combined: under 2,000 words
- MEMORY.md index: under 200 lines (silently truncated beyond this)
- Individual skill body: under 2,000 words, 3,000 absolute max
Keeping CLAUDE.md Current
#shortcut: Press during any session to capture learnings into CLAUDE.md/revise-claude-md: Reflects on the full session and drafts additions as diffs- Quality scoring: The
claude-md-improverskill scores on 6 axes — commands, architecture, patterns, conciseness, currency, actionability
The Decision Framework: CLAUDE.md vs. Memory
| Scenario | Where it belongs |
|---|---|
| Permanent gotcha every session needs | CLAUDE.md Gotchas section |
| Known bug being fixed this sprint | Memory file, project type |
| Workaround for a permanent bug | CLAUDE.md Gotchas section |
| Design decision with rationale | Memory file, project type |
| Code convention affecting every file | CLAUDE.md code style section |
| Ongoing work that will complete | Memory file, project type |
Part 2
SKILL.md — Packaged Expertise
What a Skill Is
A skill is a modular, self-contained expertise package with progressive disclosure: metadata always in context, SKILL.md body loads on trigger, references/ files load on demand.
├── SKILL.md ← required: core instructions
├── references/ ← loaded when SKILL.md directs Claude
├── examples/ ← working code, templates
├── assets/ ← files used in output (not loaded into context)
└── scripts/ ← executable utilities
The Description Field — The Trigger Mechanism
⚠️ Most Important LineThe description field is the single most important line in any SKILL.md. The entire loading mechanism depends on semantic matching between it and what users type.
| Quality | Example |
|---|---|
| ❌ Weak | "Provides guidance for working with hooks" — vague, no trigger phrases |
| ✅ Strong | "This skill should be used when the user asks to 'create a hook', 'add a PreToolUse hook', or mentions hook events (PreToolUse, PostToolUse, Stop)" |
Invocation Control
| Setting | User invoke | Claude invoke | Use for |
|---|---|---|---|
| (default) | Yes | Yes (auto-trigger) | General-purpose skills |
disable-model-invocation: true | Yes | No | Skills with side effects (deploy, email) |
user-invocable: false | No | Yes (background) | Project conventions applied silently |
context: fork — Isolated Execution
When set, the skill runs as an isolated subagent with no inherited conversation context. Use for parallel review workflows and independent analyzers. Do not use for skills that need to see current conversation state.
Skill Troubleshooting
- Description too vague: Add specific trigger phrases from actual user queries
- Wrong scope: Project-level skill not visible from outside that project
- YAML syntax error: Silently prevents loading — validate the frontmatter
- user-invocable: false: Trying to invoke via slash command but it's Claude-only
Part 3
Memory Files — Persistent Cross-Session Context
Architecture
~/.claude/projects/{encoded-project-path}/memory/├── MEMORY.md ← index, always loaded, max 200 lines
├── user_role.md ← type: user
├── feedback_testing.md ← type: feedback
├── project_auth_rewrite.md ← type: project
└── reference_linear.md ← type: reference
Project Path Encoding
The encoded path is your absolute path with forward slashes replaced by hyphens: /Users/sumit/my-project → -Users-sumit-my-project
If you move your project directory, memory files are orphaned. Fix: rename the directory in ~/.claude/projects/ to match the new encoded path.
The Four Memory Types
| Type | What it captures | Body format |
|---|---|---|
user | Role, expertise, preferences, communication style | Free-form facts |
feedback | Corrections and confirmations that shape behavior | rule + Why: + How to apply: |
project | Ongoing work, active decisions, known bugs | rule + Why: + How to apply: |
reference | Pointers to external resources (Jira, Slack, Grafana) | Free-form |
Feedback Type — Full Example
---
name: prefer-tanstack-query
description: User prefers TanStack Query over useState/useEffect
type: feedback
---
Always use useQuery and useMutation from TanStack Query, not useState + useEffect.
**Why:** Two coexisting patterns exist. useState/useEffect was flagged as legacy.
**How to apply:** Reference useMemberProfile.ts as the template for new hooks.
ℹ️ Team Usage Memory files are per-developer, per-machine. There is no cloud sync. To share context with teammates, use CLAUDE.md (checked into git).
Part 4
Plan Files — Session-Scoped Architecture
Created during plan mode, stored at ~/.claude/plans/{adjective}-{verb}-{name}.md. Names reference CS history (Moore, Kahn, Catmull, Naur, Eich). Plan files are not auto-deleted — they accumulate indefinitely and serve as an archive of architectural decisions.
Anatomy of a Good Plan File
- Context: Why this plan exists and the intended outcome
- Implementation steps: Specific files, schema changes, sequenced phases
- Critical files: Every file that will be touched
- Reuse callouts: Existing utilities to use, not reinvent
- Verification steps: How to confirm success end-to-end
Part 5
Reference Files and Supporting Docs
| Directory | What goes here | Loaded into context? |
|---|---|---|
references/ | Documentation, schemas, decision guides | Yes, on demand |
assets/ | Templates, images, fonts, output starters | No — used in file output |
scripts/ | Executable utilities (pandoc, validation) | No — executed, not read |
Part 6
Debugging and Troubleshooting
When CLAUDE.md Is Ignored
- Wrong location: Must be at
{project}/CLAUDE.md, not.claude/CLAUDE.md - Silent truncation: Content past the limit is dropped — front-load critical info
- Local override conflict:
.claude.local.mdtakes precedence - CLAUDE_CODE_SIMPLE=true: Disables all CLAUDE.md loading
When Memory Files Are Missing
# Project was moved? Rename the encoded directory:
mv ~/.claude/projects/-Users-sumit-old-name ~/.claude/projects/-Users-sumit-new-name
Using CLAUDE_CODE_SIMPLE=true as a Diagnostic
Set it and re-run. If behavior changes, a context file was influencing results. Re-enable CLAUDE.md, then skills, then memory — one at a time — to isolate the source.
Conclusion
Keep Each File Type Doing Its One Job
CLAUDE.mdProject orientation — architecture, commands, permanent gotchas
SKILL.mdReusable expertise — packaged workflows that load when needed
Memory filesCross-session knowledge — preferences, decisions, external resources
Plan filesPre-execution architecture — scope, phases, verification
Use Claude → Notice what it didn't know → Press# to capture learnings→ Review with
/revise-claude-md → Repeat
The files get better. The conversations get more useful. The ramp-up time on returning to a project shrinks toward zero.