The Landscape

Context Management

Mixed15 min

The context problem

Claude Code starts every session knowing nothing about your project. It can read files, but it doesn't know which files matter, what conventions you follow, or what mistakes to avoid. Without context, it makes generic decisions.

CLAUDE.md solves this. It's a file that Claude reads at the start of every session, containing project-specific instructions the model always follows.

CLAUDE.md is your project's constitution

Think of CLAUDE.md as a briefing document for a new team member who happens to be extremely capable but knows nothing about your project. What would you tell them on day one? Your tech stack, naming conventions, testing requirements, architecture decisions, things to avoid. That's your CLAUDE.md.

The hierarchy

CLAUDE.md files follow a precedence order. Higher levels override lower levels:

  1. Managed policy - organization-level rules (set by admins, cannot be overridden)
  2. Project CLAUDE.md - ./CLAUDE.md or ./.claude/CLAUDE.md in your repo root
  3. User CLAUDE.md - ~/.claude/CLAUDE.md (your personal global instructions)

Project-level is where you'll spend most of your time. It lives in your repo and gets committed to git, so the whole team shares the same context.

Writing a good CLAUDE.md

Keep it under 200 lines. Claude reads this on every session start, so brevity matters. Focus on what's unique about your project.

CLAUDE.md
# My Project
 
## Tech Stack
- Next.js 15 with App Router
- TypeScript strict mode
- Tailwind CSS
- PostgreSQL with Drizzle ORM
 
## Conventions
- Use named exports, not default exports
- All components in src/components/
- API routes in src/app/api/
- Database queries go through src/lib/db/
 
## Testing
- Run tests: `npm test`
- Run type check: `npx tsc --noEmit`
- All new features need tests
 
## Things to avoid
- Never use `any` type
- Don't install new dependencies without asking
- Don't modify the database schema without discussion

What to include:

  • Tech stack - framework, language, database, key libraries
  • Conventions - naming, file structure, patterns
  • Commands - how to test, build, lint, deploy
  • Constraints - what not to do, common mistakes, gotchas

What to leave out:

  • Generic programming advice (Claude already knows)
  • Full API documentation (too long, use @-imports instead)
  • Content that changes frequently (use @-imports to reference live files)

@-imports

For context that lives in other files, use the @ import syntax:

CLAUDE.md
# My Project
 
See @README.md for project overview.
See @docs/architecture.md for system design.
See @docs/api.md for API documentation.

Claude will read the referenced files when it processes the CLAUDE.md. This keeps your CLAUDE.md short while still providing rich context.

Import selectively

Don't import everything. Each imported file uses context window space. Import only the files Claude needs for most tasks. For specialized context, let Claude read files on demand during the session.

Settings files

Claude Code has two settings files per project:

.claude/settings.json - shared settings, committed to git. Team-wide permissions, allowed commands, denied commands.

.claude/settings.local.json - personal settings, gitignored. Individual overrides, personal preferences, local API keys.

.claude/settings.json
{
  "permissions": {
    "allow": ["Read", "Glob", "Grep", "Bash(npm test)"],
    "deny": ["Bash(git push --force*)"]
  }
}
.claude/settings.local.json
{
  "permissions": {
    "allow": ["Bash(npm run dev)"]
  }
}

Local settings merge with shared settings. If shared settings deny something, local settings cannot override that denial.

Path-specific rules

For large repos where different directories have different conventions, use .claude/rules/*.md files with paths: frontmatter:

.claude/rules/frontend.md
---
paths:
  - src/components/**
  - src/app/**
---
 
Use React Server Components by default.
Only add "use client" when the component needs interactivity.
All components must have TypeScript props interfaces.
.claude/rules/api.md
---
paths:
  - src/app/api/**
---
 
All API routes must validate input with Zod.
Always return proper HTTP status codes.
Include rate limiting headers.

These rules activate only when Claude is working on files matching the paths. This keeps context focused and avoids loading irrelevant instructions.

Managing the context window

Claude Code has a 200K token context window. That's large but not infinite. During long sessions, the window fills up with conversation history, file contents, and command outputs.

/compact

When the context window gets full, use /compact to summarize the conversation:

> /compact

Claude condenses the conversation history into a summary, freeing up space. The summary preserves key decisions, current task state, and important file paths. Details of completed work are compressed.

Auto-compaction

Claude Code automatically compacts when the context window is nearly full. You don't have to manage this manually, but proactive compaction before a complex task gives Claude more room to work.

What gets compacted

  • Completed tasks (decisions preserved, details compressed)
  • File contents that were read but aren't actively being edited
  • Command outputs that have been processed

What survives compaction

  • Current task state and next steps
  • File paths being actively modified
  • Unresolved errors
  • Your instructions from this session
  • Key decisions and their rationale

Putting it all together

A well-configured project looks like this:

your-project/
  CLAUDE.md                          # Project context
  .claude/
    settings.json                    # Shared permissions (committed)
    settings.local.json              # Personal overrides (gitignored)
    rules/
      frontend.md                   # Rules for frontend code
      api.md                        # Rules for API code

This gives Claude the context it needs to make good decisions, the permissions to act safely, and path-specific rules for different parts of your codebase.

Ex

Create your project's CLAUDE.md

Pick a real project you work on and create a CLAUDE.md for it:

  1. Create a CLAUDE.md in the project root
  2. Include: tech stack, conventions, commands, constraints
  3. Add 1-2 @ imports for important documentation files
  4. Keep it under 200 lines
  5. Start Claude Code and verify it reads your CLAUDE.md (ask "what do you know about this project?")
Start with just the tech stack and 3-4 key conventions. You can iterate on the CLAUDE.md over time as you discover what Claude needs to know.
Check that Claude mentions your CLAUDE.md content by asking "what conventions should you follow in this project?" early in a session.

A minimal but effective CLAUDE.md:

CLAUDE.md
# Project Name
 
## Stack
- Next.js 15, TypeScript, Tailwind, Prisma, PostgreSQL
 
## Commands
- `npm run dev` - start dev server
- `npm test` - run tests
- `npx tsc --noEmit` - type check
 
## Conventions
- Named exports only
- Components in src/components/
- Server Components by default, "use client" only when needed
 
## Don't
- Use `any` type
- Skip tests for new features
- Modify prisma/schema.prisma without discussion
 
See @README.md for project overview.

After starting Claude Code, ask "what project is this?" - Claude should reference your CLAUDE.md content in its response. If it doesn't, check the file is in the project root and properly formatted.

Ex

Set up path-specific rules

If your project has distinct areas (frontend, backend, API, tests), create path-specific rules:

  1. Create .claude/rules/ directory
  2. Add at least two rule files with paths: frontmatter
  3. Test by asking Claude to work on files in each path and verify it follows the right rules
Good candidates for separate rules: API routes vs UI components, test files vs source files, configuration vs application code.
.claude/rules/tests.md
---
paths:
  - src/**/*.test.ts
  - src/**/*.test.tsx
  - tests/**
---
 
Use vitest for all tests.
Prefer integration tests over unit tests.
Mock external services, never mock internal modules.
Every test file needs at least one happy path and one error case.

Verify by asking Claude to write a test - it should follow these conventions. Then ask it to write a component - these test rules should not be active.

CLAUDE.md is the single highest-leverage thing students will set up in this course. A good CLAUDE.md turns Claude from a generic coding assistant into a team member who knows your project. Encourage students to start small and iterate - they'll discover what Claude needs to know as they use it.