Large Project Management
Learning Outcomes
- Manage context window effectively in large projects
- Master the /compact command for long sessions
- Decompose large tasks into AI-friendly units
- Work with monorepos and multi-package projects
- Use memory and project persistence features
Lesson Plan
| Segment | Duration | Topic |
|---|---|---|
| Intro | 3 min | Why large projects need different strategies |
| Explain | 10 min | Context window management |
| Demo | 12 min | /compact and session strategies |
| Explain | 10 min | Task decomposition for large codebases |
| Demo | 12 min | Working with a monorepo |
| Demo | 8 min | Memory and project persistence |
| Wrap-up | 5 min | Key takeaways |
Before You Begin
Pre-work:
- Complete Lesson 8
- Have access to a large project (100+ files, multiple directories)
Shopping List:
- Claude Code installed
- A large codebase (if you don't have one, clone a popular open-source project)
- Multiple terminal windows available
Small projects (under 20 files) are easy — Claude can see everything. Large projects (100+ files) introduce challenges:
The context problem:
- Claude can't hold your entire codebase in context
- Reading too many files dilutes focus
- Long conversations lose earlier context
The navigation problem:
- Claude needs to find the RIGHT files among hundreds
- Related code may be spread across many directories
- Imports and dependencies form complex webs
The scope problem:
- Changes ripple across more files
- Reviews become harder (more files touched)
- Bugs have more places to hide
The solution isn't to avoid large projects — it's to develop strategies that work within context limits.
Strategy 1: Focused sessions One task per session. Start fresh for each distinct piece of work.
Session 1: Fix the authentication bug
Session 2: Add the new feature
Session 3: Refactor the database layer
Strategy 2: The /compact command When a session gets long, compress it:
> /compact
Claude summarises the conversation so far, freeing context space while preserving key decisions and context.
What /compact actually does — before and after:
Before compacting (35 messages deep, context is 80% full):
Context: [message 1][message 2]...[message 35]
↓ full conversation history ↓
- Initial project discussion
- 3 false starts on the auth module
- File reads (12 files)
- 2 bugs found and fixed
- Current task: adding email verification
After running /compact:
Context: [SUMMARY]
- Working on auth module in src/services/auth/
- Decided on JWT + refresh tokens (not sessions)
- Created: authService.ts, tokenService.ts, authMiddleware.ts
- Fixed: race condition in token refresh, missing expiry check
- Current task: adding email verification to signup flow
- Key constraint: must use existing emailService from src/lib/
[END SUMMARY]
[message 36 onward...]
The summary preserves decisions, completed work, and current state — but discards the actual back-and-forth of getting there. You lose the ability to reference "what you said 20 messages ago" but gain a fresh context window for the work ahead.
When to compact:
- After 30+ messages
- When Claude starts repeating itself
- When quality noticeably drops
- Before a complex new task within the same session
Strategy 3: Front-load context Put the most important information in your FIRST message:
> I'm working on the payment processing module.
> Key files:
> - src/services/PaymentService.ts (main logic)
> - src/types/payment.ts (types)
> - src/api/payments.ts (endpoints)
>
> I need to add refund support.
Strategy 4: Reference, don't paste Instead of pasting entire files, point Claude to them:
> Read src/services/PaymentService.ts and src/types/payment.ts,
> then I'll explain what I need.
Claude reads files efficiently — it knows to focus on the relevant parts.
Large features need decomposition (see Vibe Coding lesson 0.c). In Claude Code specifically:
The planning session:
> I need to add a full reporting system to this app. Before we
> start implementing, help me break this into independent tasks
> that we can tackle one at a time.
Claude will suggest a decomposition. You refine:
> Good breakdown. Let's structure it as:
> 1. Data layer (types + database queries) — Session 1
> 2. API endpoints — Session 2
> 3. Frontend components — Session 3
> 4. Integration + testing — Session 4
Each session gets its own focused context:
- Session 1 only reads database-related files
- Session 2 reads the types from session 1 + API patterns
- Session 3 reads types + existing component patterns
- Session 4 reads everything needed to connect them
Cross-session communication: Between sessions, information passes through:
- Committed files (session 2 reads what session 1 committed)
- CLAUDE.md (add notes about in-progress work)
- Your own notes (tell the next session what was decided)
Worked example — decomposing a reporting feature into 4 sessions:
The feature: "Add a dashboard with weekly/monthly reports showing user activity, revenue trends, and top products."
Session 1 — Data layer (types + queries):
> I'm building a reporting dashboard. This session: data layer only.
>
> Create:
> 1. src/types/report.ts — types for WeeklyReport, MonthlyReport,
> RevenueData, ActivityMetrics, TopProduct
> 2. src/db/queries/reports.ts — database queries that aggregate
> the raw data into report shapes
>
> Constraints:
> - Use our existing db connection from src/lib/database.ts
> - Queries should accept a dateRange parameter
> - Return typed results matching the interfaces
Commit the result. Session 1 is done.
Session 2 — API endpoints:
> I'm continuing the reporting dashboard. Session 1 created the
> types and queries (already committed in src/types/report.ts
> and src/db/queries/reports.ts).
>
> This session: create API endpoints.
> - GET /api/reports/weekly?start=DATE&end=DATE
> - GET /api/reports/monthly?month=YYYY-MM
> - GET /api/reports/top-products?limit=N&period=weekly|monthly
>
> Follow the same pattern as our existing endpoints in src/api/users.ts
Session 3 — Frontend components:
> Continuing the reporting dashboard. The API is complete.
>
> This session: build the React components.
> - src/components/reports/ReportDashboard.tsx (layout + date picker)
> - src/components/reports/RevenueChart.tsx (line chart)
> - src/components/reports/ActivityTable.tsx (table with sorting)
> - src/components/reports/TopProductsList.tsx (ranked list)
>
> Use the chart library already installed (recharts).
> Follow the component patterns in src/components/users/ for style.
Session 4 — Integration + testing:
> Final session for the reporting dashboard. Components and API
> exist but aren't connected.
>
> This session:
> 1. Wire the dashboard to the API (add useReport hook)
> 2. Add loading/error states
> 3. Add the route to the app router
> 4. Write integration tests for the full flow
Each session is focused, reviewable, and builds on committed work from previous sessions. No session needs to hold the entire feature in context.
Monorepos have multiple packages, each with their own context:
Navigate first:
> What packages are in this monorepo? Show me the workspace structure.
Scope your session:
> I'm working in the packages/api/ package specifically.
> Focus there unless I mention a shared package.
Cross-package work:
> I need to add a new type to packages/shared/types/ and then
> use it in both packages/api/ and packages/web/.
CLAUDE.md per package: For monorepos, consider CLAUDE.md at multiple levels:
project-root/
├── CLAUDE.md # Overall architecture, workspace commands
├── packages/
│ ├── api/
│ │ └── CLAUDE.md # API-specific conventions
│ ├── web/
│ │ └── CLAUDE.md # Frontend-specific conventions
│ └── shared/
│ └── CLAUDE.md # Shared package rules
Claude reads the most relevant CLAUDE.md based on where you're working.
Example root CLAUDE.md for a monorepo:
# Project Architecture
Monorepo with 3 packages (pnpm workspaces):
- packages/api — Express.js REST API (port 3001)
- packages/web — Next.js frontend (port 3000)
- packages/shared — Shared types, utils, and validation
## Commands
- pnpm dev — starts all packages
- pnpm test — runs all tests
- pnpm build — builds in dependency order
## Cross-Package Rules
- Shared types live in packages/shared/types/
- Never import directly between api and web
- All cross-package imports go through packages/shared
This tells Claude the architecture immediately, without it needing to explore the file tree. The first message of any session in this monorepo starts with full context of how the pieces fit together.
Claude Code has features for persisting context across sessions:
Session resume:
claude --resume
Picks up your last conversation with full context intact. Use when you need to continue exactly where you left off.
Project memory: Claude can remember facts about your project across sessions:
> Remember: we decided to use cursor-based pagination everywhere.
> The cursor is an encoded timestamp.
In future sessions:
> What pagination approach did we decide on?
When to use memory vs CLAUDE.md:
- CLAUDE.md: permanent project conventions (for the whole team)
- Memory: personal decisions, work-in-progress state, temporary context
Example — using memory for in-progress work:
End of session:
> Remember: the reporting dashboard is half done. Sessions 1-2 are
> complete (types, queries, API). Session 3 (frontend components) is
> next. The chart library is recharts. DatePicker is already built
> at src/components/ui/DatePicker.tsx.
Start of next session:
> What's the status of the reporting dashboard?
Claude recalls the context, and you can jump straight into Session 3 without re-explaining the architecture.
Session strategies for ongoing work:
| Pattern | When to Use |
|---|---|
| Fresh session each task | Default — clean context, focused work |
| Resume previous | Continuing complex multi-message work |
| Compact + continue | Long session, still same problem |
| Multiple parallel sessions | Independent tasks (see lesson 0.c) |
Choosing the right strategy — a decision flowchart:
Ask yourself:
- Is this a new, independent task? → Fresh session
- Am I continuing exactly where I left off? → Resume (
claude --resume) - Am I in a long session but switching focus? → Compact then continue
- Do I have multiple independent tasks? → Parallel sessions (one per terminal)
The most common mistake is using one long session for everything. A fresh session for each task means Claude always starts with full context budget, focused entirely on your current problem.
Questions & Answers
Key Takeaways
- One task per session — the simplest and most effective strategy
- Use /compact proactively every 25-30 messages
- Front-load context — tell Claude what area you're working in first
- Decompose — large features become multiple focused sessions
- Monorepos: scope explicitly, use CLAUDE.md per package
- Resume for continuity, fresh sessions for focus
Next Steps: In Lesson 10 — Production Workflows & Automation, you'll learn to integrate Claude into CI/CD, batch operations, and team workflows.