How to Do Refactoring Legacy Code on Claude Code
The most effective way to refactor legacy code on Claude Code is to break the work into isolated, single-responsibility prompts: one file or module at a time, with clear before/after intent. Claude Code handles complex transformations well when you give it bounded scope. For large codebases, expect heavy token usage. Track your limits in real time with Usagebar to avoid a mid-refactor lockout.
- Legacy refactoring sessions consume significantly more tokens than greenfield work because Claude reads context across many files
- Claude Pro and Max plans have 5-hour rolling usage windows. Hitting the cap mid-refactor means waiting before you can continue
- Scoping each prompt to one module or concern reduces both errors and token burn
What makes refactoring legacy code different in Claude Code?
Legacy codebases present a specific challenge: the context window fills up fast. Claude Code needs to understand what code does before it can safely change it, which means loading multiple files simultaneously. Unlike greenfield tasks where you write net-new code, refactoring requires Claude to hold the original behavior in mind while proposing a transformation.
This leads to two practical problems developers run into quickly: context overload (Claude loses track of earlier files mid-session) and usage spikes (token counts balloon when Claude reads large legacy files). Both are solvable with the right workflow.
How to set up your refactoring workflow in Claude Code
1. Define scope before opening Claude Code
Before starting a session, identify the smallest unit of change that delivers value: a single service class, a utility module, or a group of related functions. Write this scope down. You will paste it directly into your first prompt.
2. Use /init or a targeted CLAUDE.md to give Claude context
For persistent projects, a CLAUDE.md file at the repo root tells Claude Code the tech stack, conventions, and patterns to follow. According to Anthropic's Claude Code documentation, this file is automatically loaded into context at the start of each session, meaning you don't have to re-explain the codebase each time.
For a legacy project, a minimal CLAUDE.md might include:
- Language version and framework (e.g., Python 3.8, Django 2.2)
- Known anti-patterns in this codebase to watch for
- Target state (e.g., "moving from class-based views to function-based")
- Test framework used (so Claude generates compatible tests)
3. Load only the files you need
Use /add to selectively bring files into context rather than relying on Claude to explore the whole repo. For legacy work, this is critical. Loading 30 files when you only need 5 wastes tokens and muddies Claude's reasoning about the specific change.
4. Prompt with explicit intent and constraints
Effective refactoring prompts follow a clear structure:
- What: "Refactor
UserAuthServiceto remove direct database calls" - How: "Extract DB logic into a
UserRepositoryclass" - Preserve: "Keep all existing method signatures, don't change the public API"
- Test: "Add unit tests for the new repository class using pytest"
This pattern keeps Claude focused and prevents it from making broad stylistic changes you didn't ask for.
5. Use /edit for targeted in-file changes
When you want to refactor a specific function rather than an entire file, the /edit slash command lets you describe the exact transformation. This is more token-efficient than asking Claude to rewrite a full file and re-read all surrounding code. According to the Claude Code slash commands reference, /edit operates on a bounded selection, which keeps context tight.
6. Commit incrementally between sessions
Each refactored module should be committed before moving on. This gives you a clean rollback point and means you can pause a session, let your usage window reset, and resume from a known-good state. Refactoring legacy code rarely fits in one sitting.
Common mistakes when refactoring with Claude Code
Asking Claude to refactor the entire codebase at once
This is the most common mistake. A prompt like "refactor all the legacy code in /src to use modern patterns" will produce inconsistent results, burn through your usage limit, and be difficult to review. Break it into modules.
Not specifying what to preserve
Claude will try to improve code it reads. Without explicit constraints ("don't rename public methods", "keep backward compatibility with v1 API"), you risk getting a refactor that's technically cleaner but breaks downstream callers. Always state what must not change.
Skipping tests
Legacy code often lacks tests. Ask Claude to write characterization tests (tests that capture current behavior) before refactoring, then verify the refactored version passes them. This is a standard technique for safely modernizing legacy systems, described in detail in Michael Feathers' foundational work on the subject.
Ignoring token usage mid-session
Legacy refactoring sessions are token-intensive. If you're working on a critical PR and hit the usage cap, you're locked out for up to 5 hours. Monitoring your usage in real time means you can wrap up a logical unit before the limit hits, rather than getting cut off mid-change. You can check current usage with the /usage command in Claude Code, via claude.ai/settings/usage, or with Usagebar for passive, always-visible tracking in the macOS menu bar.
How to manage usage limits during a long refactoring session
Refactoring legacy code is one of the highest-token tasks in Claude Code. A single session touching five or six legacy files can push you to 75-90% of your usage window before you've finished the work. According to Anthropic's usage limit guidance, understanding when your window resets lets you pace complex work across sessions intentionally.
Developers working on long refactors often find it useful to have a passive indicator of their usage level. Usagebar is a macOS menu bar app that shows your Claude Code usage in real time, with alerts at 50%, 75%, and 90% so you know when to wrap up a module and commit before the session ends. It stores credentials securely in macOS Keychain and shows exactly when your usage window resets, so you can plan the next session without guessing. It's available on a pay-what-you-want model, with a free option for students.
For tips on keeping token counts lower during refactoring, see the guide on how to reduce Claude Code token usage.
Refactoring workflow: quick reference
| Step | Action | Claude Code tool |
|---|---|---|
| 1 | Define module scope and target state | CLAUDE.md or session prompt |
| 2 | Load only relevant files | /add |
| 3 | Write characterization tests for current behavior | Prompt: "write tests for current behavior" |
| 4 | Refactor with explicit constraints | /edit or targeted prompt |
| 5 | Verify tests still pass | Prompt: "run tests and fix failures" |
| 6 | Commit and check usage before next module | /usage or Usagebar |
Key takeaways
- Scope each refactoring session to a single module or file to avoid context overload and token waste
- Use
CLAUDE.mdto persist project conventions so you don't re-explain the codebase every session - Always specify what must be preserved (public API, method signatures) to prevent unintended breakage
- Write characterization tests before refactoring so you can verify behavior is unchanged
- Use
/editfor bounded in-file changes and/addto control which files enter context - Monitor your usage with
/usageor Usagebar to avoid a mid-PR lockout during heavy sessions
Sources
- https://support.claude.com/en/articles/11145838-using-claude-code-with-your-pro-or-max-plan
- https://support.claude.com/en/articles/9797557-usage-limit-best-practices
- https://code.claude.com/docs/en/slash-commands
- https://usagebar.com/blog/how-to-reduce-claude-code-token-usage
- https://usagebar.com/blog/claude-code-usage-statistics-command
- https://usagebar.com/blog/when-does-claude-code-usage-reset
Track Your Claude Code Usage
Never hit your usage limits unexpectedly. Usagebar lives in your menu bar and shows your 5-hour and weekly limits at a glance.
Get Usagebar