"This component's import statement is missing," Claude Code told me — and I frowned. The component definitely existed. I had written it twenty minutes earlier.
The catch: I had written it in a different repository's session.
This kind of context bleed is one of the quiet frustrations of running multiple projects in Claude Code simultaneously. It isn't a bug — it was my fault for letting the boundaries between projects get fuzzy.
At one point I was juggling a backend API, a frontend app, and a separate web service all at the same time. As soon as I started paralleling all three, I ran into context confusion, mounting costs, and constant uncertainty about when to restart sessions. This article is a record of what actually helped — and what I stopped doing — after three months of this.
What "Context Contamination" Looks Like in Practice
Claude Code anchors each session to the CLAUDE.md file and the current directory at startup. Open two terminals pointing at two different repos, and in theory they run as fully independent contexts.
The problem creeps in through verbal bridging. If you describe how something works in Project A while issuing a command for Project B, Claude Code incorporates that explanation into Project B's context. The result: it starts referencing functions and patterns that exist in neither codebase.
The fix is simple in principle, but takes discipline to follow: stop relaying information between projects in plain language. If Project B genuinely needs to reference something from Project A, give Claude Code the actual file — or use --add-dir, which I'll cover below.
Long-running sessions make this worse because of automatic compaction. When a session grows too long, Claude Code summarizes older messages to free up context space. Critical architectural assumptions established early in the session can get compressed away. This is manageable in a single-project workflow, but with multiple repos it becomes a persistent problem. Claude Code's compaction behavior is covered in a separate guide — worth reading before you hit this the hard way.
Writing CLAUDE.md for Each Repo Individually
The highest-leverage change I made was treating each repo's CLAUDE.md as a genuine working contract rather than a quick project description. These three additions made the biggest difference:
1. Anti-patterns specific to that codebase
## What NOT to do
- Don't add `data` to useEffect dependency arrays (causes infinite loops)
- Don't call /api/ routes directly from the client (all calls must go through middleware)
- Avoid `as any` type assertions — check src/types/index.ts firstDocumenting actual gotchas from that codebase — not generic best practices — dramatically reduces repeated mistakes. These differ per project, so don't copy and paste from repo to repo.
2. Current development phase
## Current phase
- DB schema is not finalized (no migrations yet)
- Prioritizing correctness over performance
- Auth is not implemented — add TODO comments where authentication is requiredScoping constraints like this keep Claude Code from helpfully suggesting work that is out of scope. Without this context, it will often propose optimizations or improvements that are premature.
3. Paths to key reference files
## Reference files
- API spec: docs/api/specification.md
- Type definitions: src/types/index.ts
- Environment variables: .env.exampleHaving these paths in CLAUDE.md means you don't need to paste them into every session. Claude Code reads the file at startup and knows where to look.
The quality difference between a thoughtfully written CLAUDE.md and a quick placeholder became very apparent once I had three repos running at once. More CLAUDE.md design patterns are covered here.
Making "Ending Sessions" a Deliberate Habit
I used to keep sessions running for as long as possible. I don't anymore.
Long sessions accumulate state, and with multiple projects it becomes increasingly hard to remember which session contains which context. After switching back and forth for a few hours, I'd often find myself unsure whether the Claude Code window I was looking at had already received certain context — or not.
The rules that cleaned this up:
- One task = one session. One feature, one bug fix, one investigation.
- Start each session by stating the goal in one sentence before anything else.
- Begin the next day's work in a fresh session, every time.
The third rule felt wasteful at first. In practice, anything important from the previous session should already be committed or documented. If it isn't, that's a signal to improve the workflow, not to keep the session alive.
Before ending a session, I ask Claude Code to summarize the key decisions and blockers in two to three bullet points. That summary goes into CLAUDE.md under a "Previous session" section. The next session picks up without needing to reconstruct context from scratch.
Using --add-dir for Cross-Repo References
One workflow that comes up constantly when splitting frontend and backend into separate repos: "I need the API response format to match the types the frontend is expecting." Without --add-dir, this means manually copying type definitions across — or just hoping your memory is accurate.
# Start a backend session with read access to frontend type definitions
cd backend/
claude --add-dir ../frontend/src/typesClaude Code reads ../frontend/src/types at session startup and can reference those files throughout the session. The types stay current without any copying.
A few practical notes:
- Each
--add-dirpath consumes additional context at session start. Keep it to one or two directories per session. - The flag accepts local paths only. For external docs or remote repos, download what you need first.
- If the referenced directory is large, combine this with
.claudeignoreto limit which files get scanned.
Tracking Costs Per Project
Once you have multiple repos running, total API spending becomes hard to reason about. Claude Code doesn't currently (May 2026) offer per-project cost breakdowns, so tracking has to be manual.
The /cost command at session end gives you the cost for that session. I log these in a simple note:
2026-05-05 backend (auth implementation) $1.23
2026-05-05 frontend (UI component fixes) $0.48
2026-05-05 service-x (bug investigation) $0.31
This takes ten seconds per session and makes monthly totals per project easy to calculate.
The unexpected insight: sessions I thought of as "just a quick check" were regularly costing $0.30–0.50 in file scanning and CLAUDE.md loading alone. Adding .claudeignore to each repo brought that startup cost down noticeably:
# .claudeignore
node_modules/
dist/
.next/
coverage/
*.log
*.map
Excluding build artifacts and dependency folders reduced per-session costs by roughly 20–30% in my experience. More on managing context window costs is in this guide.
What Stuck After Three Months
A few things I still do consistently:
An "out of scope" section in every CLAUDE.md. Listing what is explicitly not being worked on right now ("auth is not implemented," "caching comes later") prevents Claude Code from proposing work that would derail the current session. Since it's trying to be helpful, without this constraint it will suggest improvements that are technically correct but practically premature.
A session-start template in each repo's README:
## Claude Code session template
"Today's goal: [feature or fix].
Relevant files: src/[path].
Current blocker: [specific issue].
Constraints: [anything Claude Code should know]"Copying this and filling it in before starting a session consistently leads to better first responses. It also forces me to clarify my own thinking before delegating.
Small, frequent commits. Aiming for one logical change per commit keeps sessions more manageable. When I need to resume work after a break, the commit history gives Claude Code a reliable account of what has already been done.
Running multiple projects with Claude Code is genuinely effective — but the efficiency gains depend on keeping contexts clean. If you're starting a multi-repo setup, investing time in CLAUDE.md for each repo upfront will pay off quickly.