Optimizing Claude Code: CLAUDE.md and Context Window Management

hero

Getting Claude Code to understand your project from the first command is the difference between a useful coding assistant and a confused one. This tutorial covers four practical techniques — CLAUDE.md setup, terminal interface patterns, context window hygiene, and slash command shortcuts — that I use on every project.

overall flow from raw project to optimized Claude Code session


The Problem: Claude Code Flying Blind

When you drop Claude Code into a new repo with no context, it has to infer everything — your naming conventions, which test runner you use, which directories matter. This leads to suggestions that don't match your stack, commands that target the wrong paths, and a general back-and-forth tax on every session.

The root issue isn't Claude's capability. It's that you haven't given it a map.

Claude without CLAUDE.md — guessing every step

What I found is that three inputs break this loop cleanly: a well-written CLAUDE.md, a trimmed context scope, and a handful of slash commands you can reach for without thinking.


Section 1: CLAUDE.md — Build the Navigation Layer

Create a file called CLAUDE.md at the project root. This is the first thing Claude Code reads when it starts a session. Think of it as a README for the AI, not for humans.

Here's the minimum viable structure I use:

# Project: my-api-service

## Stack
- Python 3.11, FastAPI, PostgreSQL 15
- Package manager: uv
- Test runner: pytest (tests live in /tests)

## Coding Conventions
- Type hints required on all public functions
- Pydantic v2 models for request/response schemas
- No print() — use structlog

## Common Commands
```bash
# Run tests
uv run pytest tests/ -v

# Start dev server
uv run uvicorn app.main:app --reload

# Lint + format
uv run ruff check . && uv run ruff format .
```

## Folder Structure
app/
  routers/    # FastAPI route handlers
  services/   # Business logic
  models/     # SQLAlchemy ORM models
tests/
  unit/
  integration/

That's it. You don't need prose explanations. Claude reads this before any task and immediately knows where things live, how to run them, and what style to follow.

The gotcha I hit early on: I wrote CLAUDE.md in full paragraphs. That's wrong. Use bullet lists and code blocks. Claude parses structured text faster and wastes less of your context budget on formatting fluff.


Section 2: Terminal Interface — Text as the Control Layer

Claude Code is a terminal-native tool. There's no GUI to click through. That's a feature, not a gap.

The basic invocation:

claude "Explain the current directory structure"

But the real power is piping context directly into queries:

# Send a specific file as context
claude "What does this function do?" < app/services/auth.py

# Pipe command output into a question
pytest tests/ 2>&1 | claude "Why are these tests failing?"

# Ask about a git diff
git diff HEAD~1 | claude "Summarize what changed and flag any risks"

terminal pipe patterns feeding Claude Code

What worked for me was treating Claude Code like a Unix filter: small inputs, focused questions, actionable outputs. When you send an entire codebase as a single dump, you pay twice — once in response time, once in response quality.

For multi-turn sessions, the interactive REPL mode keeps context alive between messages:

claude
# Now in interactive mode
> Review the auth router
> What edge cases am I missing?
> Write a test for the token expiry path

Each message in the session carries the prior conversation. You're not re-explaining the project on every turn.


Section 3: Context Window — Prune Before You Feed

Claude has a hard limit on how much text it can hold in working memory at once. Blow past that limit and you get slower responses, truncated reasoning, and answers that ignore the tail end of your input.

The practical fix is two-part: exclude junk at the filesystem level, and feed selectively at query time.

Filesystem exclusions — put these in .gitignore (Claude Code respects it):

node_modules/
.venv/
__pycache__/
*.pyc
dist/
build/
.coverage
htmlcov/
*.log
.DS_Store

If you have a large generated file (like a compiled bundle or migration history) that isn't in .gitignore, add a .claudeignore file:

# .claudeignore
docs/generated/
migrations/versions/
data/fixtures/

Query-time scoping — instead of asking Claude to "look at the whole project," point it at the relevant slice:

# Focused: good
claude "Review app/services/billing.py for edge cases"

# Unfocused: wasteful
claude "Review my entire codebase for issues"

context budget — excluded vs active files

Here's a rough reference for what eats context budget:

Content Type Approximate Token Cost
100-line Python file ~800 tokens
node_modules/ (full) 500k+ tokens
Large SQL migration file 5k–20k tokens
A focused CLAUDE.md 300–600 tokens
Verbose log dump 10k–50k tokens

The math makes the rule obvious: one unexcluded node_modules blows the entire context budget before you've asked a single question.


Section 4: Slash Commands — Keyboard Shortcuts for Sessions

Once you're inside an interactive Claude Code session, slash commands are the fastest way to control state without typing long instructions.

The ones I reach for most:

/help          → List all available commands
/compact       → Summarize conversation, keep only key context
/clear         → Wipe the session and start fresh
/model         → Switch model mid-session (e.g., to Opus for hard problems)
/cost          → Check token usage for the current session

/compact deserves special attention. When a session runs long — you've gone through debugging, then refactoring, then review — the early parts of the conversation start dragging on the context budget without contributing useful signal. /compact compresses the history into a summary and resets the working window. I run it roughly every 30–40 exchanges on long sessions.

> /compact
Context compacted. Summary retained. Ready to continue.
> Now let's add the rate limiting middleware

You can also create custom slash commands for repetitive project tasks. Add a .claude/commands/ directory:

mkdir -p .claude/commands
# .claude/commands/test-check.md
Run the full test suite with coverage and summarize:
1. Which tests failed and why
2. Coverage gaps below 80%
3. Suggested fixes for failures

Now /test-check triggers that full workflow from a single command. I use this for pre-commit checks and PR review prep.

slash command routing inside a session


Closing

The core insight here: Claude Code's output quality is a function of input quality. A focused CLAUDE.md, a trimmed context scope, and a few slash commands in muscle memory will cut your per-task friction by more than any model upgrade.

Next step worth trying: add a CLAUDE.md to an existing project you know well, then compare response accuracy before and after. The difference is immediate.


🐦 Faster updates on X: @baegseungh7061
📚 More in this series: Code Intro
💌 Subscribe: Follow on X or grab the RSS

댓글