Claude can hold your entire codebase in memory — here's what I built with that
I was preparing for a large refactor — moving our auth layer from JWT to session tokens across a FastAPI + Next.js codebase. Normally I'd spend half a day mapping the blast radius: which files touch auth, which endpoints depend on the token shape, what breaks at the edge. Instead, I ran find . -name "*.py" -o -name "*.ts" | xargs cat, pasted the output into Claude with one question: "If I change the JWT payload shape, what breaks and where?" Claude came back with a precise list. Twelve files. Three edge cases I hadn't thought of. An ordering for the migration. I was done mapping in ten minutes.
The context window is the feature most engineers underuse
Claude's context window is enormous — 200K tokens for Claude 3.5 and above. That's roughly 150,000 words, or about 500 pages of dense code. A typical mid-size service layer — models, routes, utils, tests — fits comfortably. The entire business logic of most apps fits with room to spare.
Most developers treat Claude like a pair programmer who can only see the file you're currently editing. That's like hiring a senior engineer and then only showing them one function at a time. The moment you start feeding it the full picture, the quality of its answers shifts completely.
Without codebase context:
You: "How should I handle auth in this endpoint?"
Claude: Generic JWT middleware example.
With codebase context:
You: "How should I handle auth in this endpoint?"
Claude: "You already have an auth_required decorator in
app/middleware/auth.py. Use that pattern — it
handles both JWT and session tokens and integrates
with your existing UserContext model."
What I actually built with this
Once I started thinking about Claude as a system that can hold my whole codebase, a few workflows emerged that I now use constantly.
1. Architecture impact analysis
The refactor I described above. Any time I'm about to change a shared model, a base class, an API contract, or a utility function used everywhere — I feed the codebase and ask for the blast radius. It's faster and more thorough than grepping, because Claude understands semantic dependencies, not just text matches.
# Build a context dump
find . -name "*.py" | grep -v __pycache__ | grep -v .venv | xargs cat > /tmp/codebase.txt
# Feed to Claude with the question
# "If I change X, what else breaks?"
The key prompt pattern I use:
Here is the full codebase:
[paste]
Question: I'm planning to change [specific thing].
Walk me through:
1. Every file that will need updating
2. The safest order to make changes
3. Any edge cases I might miss
2. Code reviews that actually understand the system
I paste a PR diff and the relevant surrounding code, then ask Claude to review it in the context of the existing patterns in the codebase. Not "is this code correct in isolation" but "does this fit how we already do things, and are there places where this pattern is already handled better elsewhere?"
This catches the most common code review failure mode: the PR is technically correct but drifts from established patterns, duplicates logic that already exists, or names things inconsistently with the rest of the codebase.
Here is our current codebase:
[paste]
Here is the PR diff:
[paste diff]
Review this PR specifically for:
- Duplication of logic that already exists elsewhere
- Inconsistency with existing naming and patterns
- Any integration points that look risky given how other parts work
3. Onboarding new engineers faster
When a new engineer joins, the hardest thing isn't learning the tech stack — it's understanding why things are the way they are, and how the pieces connect. I now create a "codebase briefing" by feeding Claude the full repo and asking it to produce a mental model document:
Here is our codebase:
[paste]
Write a "how this codebase works" document for a new senior engineer.
Include:
- The overall architecture and data flow
- The key models and what they represent
- The most important conventions to know (naming, error handling, auth)
- The files a new developer should read first
- Things that might look surprising and why they are the way they are
The output is a living document that I update every few months. It's better than any wiki I've ever maintained manually, because it reflects the actual code rather than whoever last updated the docs.
4. Asking "what could go wrong"
Before shipping any significant change, I feed the affected subsystem and ask Claude to be adversarial:
Here is the payment processing module:
[paste]
I'm about to [describe change].
What are the three most likely ways this causes a production incident?
Be specific — reference actual lines and functions.
This is not replacing a proper review — it's a sanity check that takes two minutes and has caught real things. Race conditions in async handlers. An edge case in error recovery that I'd missed. A config value that was hardcoded in one place and would need updating.
The setup that makes this practical
The friction point is context preparation. If you have to manually assemble files every time, you won't do it consistently. Here's the script I keep in every repo:
#!/bin/bash
# context-dump.sh — build a Claude-ready codebase context
OUTPUT="/tmp/codebase-context.txt"
echo "=== CODEBASE CONTEXT ===" > "${OUTPUT}"
echo "Generated: $(date)" >> "${OUTPUT}"
echo "" >> "${OUTPUT}"
# Python files (skip venv, pycache, migrations)
find . -name "*.py" | grep -v ".venv" | grep -v "__pycache__" | grep -v "migrations" | grep -v "test_" | sort | while read f; do
echo "=== FILE: $f ===" >> "${OUTPUT}"
cat "$f" >> "${OUTPUT}"
echo "" >> "${OUTPUT}"
done
# TypeScript/React files
find . -name "*.ts" -o -name "*.tsx" | grep -v "node_modules" | grep -v ".next" | grep -v "*.d.ts" | sort | while read f; do
echo "=== FILE: $f ===" >> "${OUTPUT}"
cat "$f" >> "${OUTPUT}"
echo "" >> "${OUTPUT}"
done
SIZE=$(wc -c < "${OUTPUT}")
echo "Context ready: ${OUTPUT} (${SIZE} bytes)"
pbcopy < "${OUTPUT}" && echo "Copied to clipboard"
Run bash context-dump.sh, then paste into Claude with your question. The whole thing takes under a minute.
For very large codebases, be selective. You don't need the entire repo for every question — feed the subsystem that's relevant. Auth question? Feed the auth module, middleware, and the models it touches. Database question? Feed the models, migrations, and query layer. The power isn't in dumping everything — it's in giving Claude enough context to reason about the specific problem without gaps.
What changed in how I work
The mental shift is treating Claude less like a code generator and more like a senior engineer who has read the entire codebase. You'd never ask a senior engineer a question without any context and expect a useful answer. Give Claude the context it needs and the answers get dramatically better — not because the model changed, but because you changed how you use it.
The refactor I mentioned at the start took a day and a half instead of three. The mapping phase — which used to be the painful, error-prone part — was mostly done before I wrote a single line. That's the productivity shift. Not that Claude writes code for you. It's that you spend less time being confused about your own system.