Workflow

Refactoring

Modernize legacy code without breaking existing behavior.

Overview

Refactoring legacy code is risky without the right tools and process. Claude Code helps you modernize outdated patterns, improve code structure, and eliminate technical debt while maintaining backward compatibility. Instead of manually rewriting code and risking breaking changes, you can leverage Claude to analyze dependencies, suggest safe transformations, and execute changes incrementally.

When to use

Use this workflow when modernizing legacy codebases, eliminating code duplication, adopting new language features, restructuring for better maintainability, or preparing code for new requirements.

Step-by-step process

1

Describe the refactor target and constraints

Clearly define what needs to change and what must stay the same. Include information about existing tests, deployment constraints, and any breaking change concerns.

"Refactor our authentication module to use async/await instead of callbacks. We need to maintain the same API surface for backward compatibility, and all existing tests must pass."
2

Ask for a plan and staged rollout

Request a detailed refactoring plan that breaks the work into safe, reviewable stages. This minimizes risk and makes it easier to catch issues early.

"Create a refactoring plan with 3-4 stages. Start with the smallest, most isolated modules first. For each stage, identify which files change and what tests validate the changes."
3

Apply the refactor in small, reviewable chunks

Execute one stage at a time, reviewing each change before proceeding. Commit after each successful stage to create clear rollback points.

"Execute stage 1 of the refactoring plan. Show me the diff before applying, and run the affected tests after making changes."
4

Run tests and check performance

Validate that functionality remains unchanged and performance hasn't degraded. Look for edge cases that tests might not cover.

"Run the full test suite and check if there are any performance regressions. Also identify any edge cases that our tests don't currently cover."

Example prompts

Modernizing JavaScript patterns

"Convert all class components in src/components to functional components with hooks. Preserve all existing behavior and prop types. Create a checklist of components to migrate."

Eliminating code duplication

"I see similar authentication logic in both api/auth.ts and middleware/auth.ts. Extract the common code into a shared utility and update both files to use it."

Adopting TypeScript strict mode

"Enable TypeScript strict mode in this project. Create a migration plan that fixes each strict mode violation one directory at a time, starting with utility functions."

Restructuring for scalability

"Refactor this monolithic service.ts file into separate modules organized by domain. Maintain all existing exports so consumers don't break."

Expected outputs

Refactor plan

Step-by-step roadmap showing which files change in each stage, dependencies between stages, and validation checkpoints

Code changes

Transformed code with improved structure, modern patterns, and better maintainability while preserving functionality

Validation checklist

List of tests to run, edge cases to verify, and performance benchmarks to check before considering the refactor complete

Migration notes

Documentation of what changed, why, and any follow-up work needed for consumers of the refactored code

Best practices

Always request a plan before making changes—rushing into refactoring leads to broken code
Refactor in small stages with tests between each stage, not one big-bang change
Maintain backward compatibility unless you've explicitly confirmed breaking changes are acceptable
Keep refactoring separate from feature work—don't mix behavior changes with structural improvements
Document why the refactor was needed and what patterns to follow going forward

Common pitfalls

Refactoring too much at once

Solution: Break the work into 3-5 reviewable stages. If a stage touches more than 10 files, split it further.

Not running tests between stages

Solution: Run the test suite after every stage. If tests fail, fix them before proceeding to the next stage.

Assuming tests cover all edge cases

Solution: Ask Claude to identify edge cases not covered by tests and validate them manually or write new tests first.

Pro tips

Use git blame to understand history

""Before refactoring user.service.ts, show me the git blame and recent commits to understand why the current pattern exists.""

Start with high-test-coverage modules

""Identify which modules have the best test coverage. We'll refactor those first since they're safest to change.""

Create a deprecation path for breaking changes

""If we need to change the API, keep the old version as deprecated with a warning, and add the new version alongside it.""

Related workflows