You ask Claude to refactor the auth flow in a 400k-line monorepo, and it confidently edits the wrong service: the deprecated legacy-auth package instead of the live one, because it never loaded the right context. On a large codebase, the binding constraint is no longer “can the model write the code” but “does it have the right slice of the repo in context, and only that slice.”
These 15 tips cover how to navigate, understand, and safely modify enterprise-scale codebases with Claude Code without drowning it in irrelevant context or letting parallel sessions clobber each other.
Claude Code uses agentic search to understand your project structure automatically. Instead of pasting files or explaining the layout yourself, you can ask a question like “Explain how the authentication system works” and Claude will search for the auth-related files, identify the key components, trace the dependencies, follow the flow, and give you a grounded explanation.
Agentic Search Capabilities
Pattern Recognition: Finds similar code patterns across files
Dependency Tracing: Understands import chains and relationships
Smart Filtering: Focuses on important files, ignores noise
Cross-Reference: Links related functionality across modules
A typical onboarding question on a data platform looks like this:
Claude searches the repo, follows the import and call chains, and answers with the endpoint handlers, the transformation pipeline, the schema relationships, and the dashboard query patterns, instead of you spending a day reading files manually.
Claude Code excels where other tools fail with massive files:
Suppose you have an 18,000-line legacy React component (the kind that accretes in any long-lived app). The trick is to give Claude a precise anchor instead of asking it to hold the whole file in its head:
Optimize Claude’s performance with targeted context:
Terminal window
# Less effective: Vague request
"Optimize our application"
# More effective: Focused request
"Optimize the database queries in the UserRepository class"
# Even better: Specific context
"The getUsersWithOrders method in UserRepository has N+1 query issues.
Optimize it using eager loading."
The real constraint is the context budget, not a line count. Current models (Claude Fable 5, Opus 4.8, and Sonnet 4.6) carry a 1M-token window, but every file you pull in competes for it, and quality degrades as you fill it with irrelevant code. As a rough rule of thumb:
A focused module or a few related files: name them and let Claude load the lot.
A package spanning many files: scope the prompt to one concern (“the query layer,” “the auth middleware”) so search pulls only what’s relevant.
A whole monorepo: never load it all. Point Claude at one package via --add-dir, lean on hierarchical CLAUDE.md files, and work module by module.
Run parallel Claude Code instances, each scoped to one area of the repo. Start each one in its own terminal with the relevant working directory:
Terminal window
# Terminal 1: Frontend
claude--add-dir./frontend
# Terminal 2: Backend API
claude--add-dir./backend
# Terminal 3: Database migrations
claude--add-dir./database
# Terminal 4: Tests
claude--add-dir./tests
Then drive each session with a focused prompt, for example “Implement the new user dashboard” in the frontend instance and “Create REST endpoints for the dashboard data” in the backend one.
Use the filesystem as the handoff point between instances. One generates artifacts; the others consume them:
Instance 1: “Generate TypeScript interfaces from our API responses and write them to shared/types/api.types.ts.”
Instance 2: “Create React Query hooks using the types in shared/types/api.types.ts.”
Instance 3: “Document the types in shared/types/ with usage examples.”
Shared Workspace Patterns
project/
├── .claude/
│ ├── generated/ # AI-generated code
│ ├── templates/ # Reference implementations
│ └── workspace/ # Shared working files
├── docs/
│ └── ai-sessions/ # Session documentation
Study external patterns without copying their source into your repo (which drags in licensing baggage). Have Claude summarize the approach, then design your own:
"Find all different error handling patterns in our codebase"
"Show me all the different ways we're validating email addresses"
"Identify inconsistent naming conventions"
# Locate duplicate code
"Find similar code patterns that could be refactored"
"Show me duplicate business logic across services"
# Architecture violations
"Find all places where the presentation layer directly accesses the database"
"Show me services calling other services synchronously"
# Performance patterns
"Find all N+1 query patterns"
"Locate all synchronous I/O in request handlers"
"Show me all uncached database queries"
A security sweep is one of the highest-leverage uses of pattern recognition on a large codebase. A single prompt can surface every risky query construction at once:
A sweep like this typically surfaces a handful of distinct query-building styles and points you straight at the ones that interpolate untrusted input, instead of you auditing thousands of call sites by hand.
Large codebases fail in specific, recognizable ways. Here’s what to watch for and how to recover.
Context-window overflow on a giant file. You ask Claude to edit a 20k-line file and it loses track, edits the wrong block, or truncates. Recovery: stop loading the whole file. Anchor the change to a function name and line range, or ask for the target region first (“show me just handleSubmit”), then edit that slice in a follow-up.
Agentic search misses dynamically-referenced code. Search finds static imports but not handlers wired up by string keys, reflection, or a registry built at runtime, so a “find every caller” sweep comes back incomplete. Recovery: name the indirection explicitly (“we register routes by string in router.config.ts; trace those too”) and cross-check with a literal grep before you trust the list for a risky refactor.
Parallel instances clobber a shared file. Two sessions both edit shared/types/api.types.ts and the second silently overwrites the first. Recovery: give each instance a non-overlapping directory scope, commit (or stash) between handoffs so the filesystem is the single source of truth, and never let two instances own the same file at once.
Stale CLAUDE.md drift. A CLAUDE.md still describes the old session-based auth after you migrated to JWT, so Claude follows instructions that no longer match reality. Recovery: treat CLAUDE.md as code, review it in PRs, and periodically ask Claude to reconcile it (“compare the auth section of this CLAUDE.md against the actual auth/ package and flag anything out of date”).
The repo is too big to reason about at all. Even scoped prompts wander because the package itself is a tangle. Recovery: don’t ask for a change, ask for a map first (“produce a dependency diagram of this package and identify the three highest-coupling modules”), then refactor against that map one module at a time.
With strategies for large codebases in hand, the next lever is your day-to-day loop. Continue to Workflow Optimization to turn these one-off techniques into repeatable habits, then see Performance and Cost Management for keeping token spend in check at scale.