Claude Code uses a .claude/ directory and a CLAUDE.md file to maintain project context across sessions. Understanding this structure lets you customize Claude Code's behavior, set up project-specific instructions, and manage how it remembers things.
project/
├── CLAUDE.md # Project instructions (loaded every session)
├── .claude/
│ ├── settings.json # Project-level settings
│ └── hooks/ # Pre/post command hooks
└── ~/.claude/
├── CLAUDE.md # Global instructions (all projects)
├── settings.json # Global settings
└── sessions/ # Session history
This is the most important file. Claude Code reads it at the start of every session, treating it as persistent instructions. Think of it as a system prompt you control.
# CLAUDE.md
## Project Context
This is a Python web scraper for Medium articles.
Stack: Python 3.11, aiohttp, BeautifulSoup4, Apify SDK.
## Conventions
- Use async/await for all HTTP calls
- Error handling: catch specific exceptions, log with structlog
- Tests: pytest with async fixtures
- Commit messages: conventional commits (feat/fix/chore)
## Important Files
- src/main.py — entry point (Apify Actor)
- src/scraper.py — core scraping logic
- .actor/actor.json — Apify actor configuration
## Known Issues
- Rate limiting: Medium returns 429 after ~100 requests/minute
- Some articles have paywall redirects — check for meta refresh tags
Key rules for CLAUDE.md:
// .claude/settings.json
{
"permissions": {
"allow": [
"Bash(npm run test)",
"Bash(git commit:*)",
"Bash(git push:*)"
],
"deny": [
"Bash(rm -rf *)"
]
}
}
Settings control what Claude Code can do without asking. The permission system uses glob patterns — you can allowlist specific commands while denying dangerous ones.
Hooks let you run custom scripts before or after Claude Code commands:
// .claude/hooks/pre-commit.sh
#!/bin/bash
# Run linter before any commit
npm run lint
if [ $? -ne 0 ]; then
echo "Lint failed — fix before committing"
exit 1
fi
Claude Code stores session transcripts in ~/.claude/sessions/. Each session gets a UUID directory with the full conversation. This enables:
You can have CLAUDE.md at multiple levels: