New greenfield projects are easy with Claude Code. The harder, more valuable use case is legacy codebases — the ones with no tests, inconsistent conventions, and functions that everyone is afraid to touch.
This is where Claude Code earns its keep.
Understanding code you didn't write
The first prompt for any legacy code exploration:
Read this code and explain:
1. What it does at a high level
2. What inputs it expects and what it returns
3. What assumptions it makes about the data
4. What would break if [specific change]
Don't suggest improvements yet — just understand it first.
The "don't suggest improvements" instruction prevents Claude from jumping to "this should be refactored" before you understand what it does. Understanding first, improvement second.
Finding the blast radius
Before touching anything in a legacy codebase:
If I change [function/variable/type], what else might break?
Look for:
- Direct callers
- Indirect dependencies
- Anything that assumes specific behavior of this function
Don't change anything — just map what would need to change.
This blast radius map is more valuable than any refactor. It tells you the actual scope of work before you commit to it.
Adding tests to untested code
Adding tests to legacy code without changing behavior is delicate. The prompt:
Write tests for this function that capture its current behavior —
including any behavior that might be wrong.
Do not fix bugs in the tests. If the function returns null in an
edge case that seems like a bug, write a test that expects null.
We want to lock in current behavior before refactoring.
Then flag any behavior that looks like it might be a bug.
This is the characterization test approach: document what code does, not what it should do. This lets you refactor safely — if you change behavior unintentionally, the tests catch it.
Safe incremental refactoring
Large refactors in legacy code are high-risk. The prompt that keeps changes small:
Refactor this function. Rules:
1. Make one change at a time
2. Each change should leave tests passing
3. No change should affect external behavior
4. Flag any cases where the refactor might change behavior
Show me the first change and stop. We'll review before continuing.
The "show me the first change and stop" is critical. Claude's instinct is to refactor everything in one pass. Incremental changes are safer and easier to review.
Dealing with magic numbers and undocumented constants
This code has several magic numbers and undocumented values.
For each one:
1. What does it likely represent?
2. What would happen if it were doubled? Halved? Zero?
3. Should it be a named constant, a config value, or stay inline?
List them without changing anything.
This surfaces implicit assumptions the original developer made. Often Claude can figure out what a magic number means from context. Even when it can't, listing the questions is useful for the next code review.
When to leave legacy code alone
Not all legacy code needs to be touched. The prompt for deciding:
Given the current behavior and blast radius of this code,
is there a good reason to refactor it now? What would we gain?
What's the risk? What's the minimum change to accomplish [specific goal]
without touching anything else?
Sometimes the right answer is "don't touch it." Claude is good at making that case when the evidence supports it.
Legacy code prompts — characterization testing, blast radius analysis, safe refactoring — are in the Agent Prompt Playbook. $29.