Working in Large Codebases With Claude Code
Claude Code feels effortless on a fresh side project and noticeably less so on a 400,000-line monorepo. The tool didn't get worse — the constraints changed. On a big repo the model can't hold everything in its head, the signal-to-noise ratio of what it reads drops, and a small change can ripple through code it never looked at. The good news is that the failure modes are predictable, and a handful of habits address most of them.
This post covers five that carry the most weight: keeping the working context narrow, pushing big read-heavy exploration into subagents, giving Claude a CLAUDE.md that maps the repo, scoping a change before touching code, and verifying before you claim it's done.
Why large repos are different
Claude Code works inside a finite context window — the model's working memory for the current session. Every file it reads, every command output, every message you send occupies part of it. On a small project you never feel the ceiling. On a large one you hit it fast: read a few big modules, paste some logs, and the useful signal starts competing with noise the model has to weigh against your actual request.
Two things follow. First, more context is not better context — an over-full window makes the model slower and more likely to lose the thread. Second, the model can only reason about code it has actually seen, so on a large repo it's easy for it to confidently miss a caller, a subclass, or a config file it never opened. Most of the strategies below are really about managing those two facts.
Keep the working context narrow
The single most useful habit is to be deliberate about what Claude reads. Point it at the specific area you're working in rather than inviting it to wander the whole tree. "Look at the auth middleware in src/auth/ and the login route" gives it a tight, relevant slice; "figure out how auth works" invites it to read half the repo and burn context doing it.
Prefer targeted search over bulk reading. Claude Code can grep and glob across the codebase to locate the handful of files that matter, then read only those — that's far cheaper than reading directories wholesale. When you already know the file, name it. Precision here is not just about speed; a narrow context is one the model reasons about more reliably.
When a session has accumulated a lot of exploration and you're moving on to a different task, reset it. Claude Code provides /clear to drop the conversation and start fresh, and /compact to condense a long session down to a summary that frees up the window; run /help or check the official docs for the current behavior. The point is the habit: don't let yesterday's forty-file investigation sit in the window while you work on something unrelated today.
Delegate exploration to a subagent
Sometimes you genuinely need to read a lot to answer one question — "where does an order's total get computed across all these services?" That's exactly the job for a subagent: a separate Claude instance with its own context window that works in isolation and returns only its final summary. The noisy exploration happens over there; your main thread stays clean and receives the conclusion.
This is the large-codebase move. Instead of reading twenty files in your main session and pushing out everything else, you delegate the search, and what comes back is a focused answer plus the file paths that matter — not the twenty files themselves. You can run several such explorations in parallel when the questions are independent.
The trade-off is honest: a subagent spends a full extra context window, and the handoff is lossy — it returns a summary, not its full reasoning, so tell it exactly what to report back (the relevant files, the specific functions, the data flow). Use it when the exploration is genuinely big or read-heavy; for a quick two-file lookup, just ask directly. The large-repo takeaway is simple: keep the expensive reading out of the thread you're thinking in.
Give Claude a map: a good CLAUDE.md
On a big repo, orientation is half the battle. CLAUDE.md is a Markdown file Claude Code reads automatically at the start of a session, and its highest-value job in a large codebase is to answer "where does what live?" so the model doesn't have to rediscover the layout every time.
Keep it a map, not an essay — it shares the same context window as everything else, so a tight file beats a comprehensive one:
## Layout
- src/api/ — HTTP handlers, thin. No business logic.
- src/services/ — business logic. Handlers call these.
- src/db/ — schema + queries. Only place that touches Postgres.
- packages/ui/ — shared component library (its own CLAUDE.md).
## Commands
- Test one file: <your single-test command>
- Typecheck + lint + test before "done".
## Gotchas
- Every by-id query is scoped by account_id — unscoped = cross-tenant leak.
Two facts help in large repos specifically. Nested CLAUDE.md files in subdirectories get pulled in when Claude works inside that subtree — ideal in a monorepo where each package has its own commands. And you can factor shared content into another file and reference it, keeping the root lean. Running /init will draft a first version by scanning the repo; treat that as a starting point and trim it toward the gotchas only you know. If you'd rather start from a worked example, there's a free CLAUDE.md template and a set of skills in the claude-code-starter repo.
Scope the change before touching code
In a large system the risk isn't writing the wrong line — it's not knowing what the line touches. Before any implementation, have Claude state the plan: what will change, which files, and the riskiest assumption. In a big repo that plan is where you catch "this function has fourteen callers and you're changing its signature" before the edit, not after the test suite goes red.
Ask it to find the blast radius first. "Before editing, list every caller of this function and every test that exercises it" is a cheap grep that turns a blind change into a scoped one. Then keep the change itself small and local. If a task naturally splits into "refactor the interface" and "add the new behavior," do them as separate passes — a diff you can hold in your head is one you can actually review, and a smaller surface is a smaller chance of breaking something three directories away.
Verify before you claim it's done
The most expensive habit to skip on a large codebase is verification, because the feedback loop is longer and the surface area for regressions is wider. A green typecheck or a successful build is not proof the change works — it's proof the types line up. If the change has a runtime surface, exercise it: call the endpoint, run the specific test, trigger the flow, and read the actual output.
Be explicit about this in the session and in your CLAUDE.md: name the single-test command so Claude runs the relevant test rather than the whole suite, and define "done" as the checks actually passing. If Claude says "verified" but you don't see evidence — a response body, a log line, a test result — treat the gate as skipped and ask for the run. On a small project a missed regression is a quick fix; in a large one it can hide for a week.
The takeaway
Working in a large codebase with Claude Code is mostly context discipline. Read narrowly and reset when you switch tasks. Push big, noisy exploration into a subagent so the answer comes back without the noise. Give the model a CLAUDE.md that maps the repo and names the traps. Scope every change to its blast radius before editing, and verify by exercising the code, not by trusting a green build. None of it is exotic — it's the difference between an agent that guesses at a system it can't fully see and one you've set up to see the parts that matter.
Related guides
- Using MCP Servers With Claude Code
- A Pre-Merge Review Pipeline With Claude Code
- How to Prompt Claude Code Effectively
Set up Claude Code the right way
Start free with the open-source starter — a ship skill, an adversarial-reviewer subagent, a bug-hunt workflow, and a CLAUDE.md template. Want the full kit? The Pro Pack adds 6 skills, 3 subagents, 3 workflows, 4 templates and a handbook.