This is Part 2 of a series on plan-based development with Claude Code. Today we explore why writing the plan before the code changes everything.
The Problem with “Just Start Coding”
When faced with a complex feature request, the instinct is to dive straight into code. Create a branch, start typing, and figure it out as you go. This approach has serious downsides:
- Hidden complexity surfaces late: You discover architectural issues after you’ve already built the scaffolding
- Context switching: You constantly pause coding to research, losing flow state
- Incomplete mental models: Without a written plan, you hold everything in your head—and drop things
- Poor communication: Teammates can’t review your approach until they see the code
The Solution: Plans as First-Class Artifacts
We adopted a practice where every significant feature starts with a markdown planning document. Before writing a single line of implementation code, we write the plan.
Here’s an example from our plans/ directory structure:
plans/├── feature-effect-refactor.md # Effect TS integration plan├── feature-turbo.md # Turborepo optimization plan├── feature-test-coverage.md # Test infrastructure improvements├── feature-claude.md # Claude Code commands setup├── feature-auth-cleanup.md # Authentication system refactor├── feature-ai-tools.md # AI tooling additions└── ... (65+ planning documents)What Makes a Good Plan Document
Our planning documents follow a consistent structure:
# Feature: [Name]
## ProblemClear description of what we're solving and why.
## SolutionHigh-level approach with rationale for key decisions.
## Implementation Steps1. [ ] Step one with specific file paths2. [ ] Step two with dependencies noted3. [ ] Step three with testing criteria
## Files to Modify- `packages/auth/src/index.ts` - Add conditional provider logic- `apps/server/src/routes/health.ts` - Add new endpoint
## Technical DecisionsKey architectural choices and trade-offs.
## StatusTracking completion of each phase.The Plan as a Living Document
The magic happens when plans become living documents. As we implement:
- Check off completed steps - Creates visible progress
- Add discoveries - Document unexpected issues as they arise
- Update decisions - When you pivot, record why
- Link to commits - Connect plans to actual code changes
Here’s a real example from our Effect TS integration plan:
## Migration Strategy
### Phase 1: Foundation1. [x] Create `@bts/effect` package2. [x] Implement error types3. [x] Create configuration service4. [x] Add logger and telemetry services
### Phase 2: Database Layer1. [x] Add Effect to `@bts/db`2. [x] Implement Database service3. [ ] Create repository pattern for entities
### Phase 3: API Layer1. [ ] Add Effect integration to `@bts/api`2. [ ] Implement error mapping3. [ ] Add runtime middlewareBenefits We’ve Observed
After six months of plan-based development:
For individuals:
- Reduced “what was I doing?” moments after interruptions
- Easier to resume work after context switches
- Better at estimating complexity (plans expose hidden work)
For teams:
- Code reviews are faster—reviewers understand intent
- Onboarding is easier—new devs read plans to understand features
- Post-mortems are richer—we have documented decision trails
For the codebase:
- More consistent architectural patterns
- Better documentation (plans often become README content)
- Fewer “I don’t know why this works this way” mysteries
When to Skip the Plan
Not everything needs a formal plan. Quick guidelines:
- Plan needed: Multiple packages affected, new patterns introduced, significant architectural decisions
- Plan optional: Single file changes, bug fixes with obvious solutions, dependency updates
- Skip the plan: Typo fixes, formatting changes, configuration tweaks
The key insight: The time spent planning is almost always recovered through faster implementation and fewer revision cycles.
Next up in Part 3: How Turborepo orchestrates complexity and makes our 60+ package monorepo manageable.