The old codebase you inherited—15-year-old PHP, undocumented Java monoliths, Rails apps running on end-of-life frameworks—is no longer a problem you have to solve alone. The ability to modernize legacy code with AI has gone from theoretical to genuinely practical in the last two years, and the engineers who figure this out first are clearing technical debt in months instead of quarters.
What AI Actually Does Well With Legacy Code
Before you throw an AI tool at a 200k-line codebase and expect magic, understand where these tools earn their keep.
- Summarizing undocumented code. Paste a function that has no comments, no tests, and a name like
processData2_final_v3. A capable model like Claude or GPT-4o will explain what it does in plain English within seconds. This alone is worth the cost of the tool. - Generating test coverage for existing functions. AI is unusually good at reading a function and writing unit tests that cover its observable behavior—even without understanding the business logic. This gives you a safety net before any refactoring begins.
- Translating between languages and frameworks. Python 2 to Python 3, jQuery spaghetti to modern JavaScript, class-based React to hooks—these mechanical translations are exactly the kind of pattern-matching that large language models handle well.
- Writing migration scripts. Schema changes, data normalization, config format updates. AI can draft these scripts faster than you can, and you review and run them.
The Modernization Workflow That Actually Works
Don't start by rewriting. Start by understanding. The biggest mistake engineers make with legacy codebases is jumping to solutions before they know what the code does. AI makes the understanding phase dramatically faster.
Step 1: Map the codebase
Use a tool with a large context window—Claude with extended context or a Cursor session with the whole repo indexed—and ask it to explain the architecture. What are the entry points? What does the data flow look like? What modules are coupled to everything else? You want a map before you start digging.
Step 2: Generate tests before touching anything
Pick the most critical, most fragile-looking module. Feed it to an AI model and ask it to write a test suite that documents current behavior. These tests don't need to be perfect—they need to catch regressions. Run them, fix any that fail on valid behavior, and then commit. Now you have a net.
Step 3: Refactor incrementally with AI as a pair
Don't ask AI to rewrite the whole thing. Identify one well-scoped function or class, describe the desired outcome, and let the model do a first pass. Review the diff yourself. AI tends to over-engineer or introduce subtle behavioral changes—you're the domain expert, it's the typist. Iterate until the tests pass.
Step 4: Automate the mechanical changes
Anything repetitive—renaming conventions, updating import paths after a restructure, migrating a config format—can be scripted with AI help. Describe the pattern, have AI write a script, test it on a single file, then run it across the repo.
Tools Worth Using for Legacy Code Work
Not all AI coding tools are equally useful for legacy work. The key factor is how much context they can hold at once.
- Cursor with codebase indexing is the most practical for day-to-day refactoring. It can reference the full repo when answering questions about a specific function.
- Claude with extended context is useful for deep analysis tasks—paste an entire module, ask for a modernization plan, get back structured reasoning.
- Aider (terminal-based) works well for engineers who prefer command-line flows and want AI to commit changes directly. Strong for targeted rewrites.
- GitHub Copilot is better for greenfield than legacy, but its inline suggestions are still useful during manual refactoring sessions.
Modernize Legacy Code with AI: A Realistic Timeline
What does a real modernization project look like with AI in the loop?
A mid-size Rails 4 app being upgraded to Rails 7—with roughly 80k lines of code and minimal test coverage—might have taken a small team six months without AI assistance. With AI tools handling test generation, automated deprecation fixes, and explaining obscure ActiveRecord patterns, experienced teams are reporting that same scope of work compresses to eight to twelve weeks.
The compression isn't magic. It comes from specific places:
- Documentation and comprehension time cut by 60–70%
- Boilerplate test writing automated almost entirely
- Mechanical API migrations handled in hours rather than days
- Fewer context-switching costs because the AI holds the context for you
The work that still takes human time: architectural decisions, business logic you don't fully understand, data migration edge cases, and final QA. AI doesn't replace judgment—it removes the tedious work that was blocking you from using your judgment.
What AI Can't Do (Don't Learn This the Hard Way)
AI is confident when it's wrong. This is especially dangerous with legacy code, where the model has no way to know about company-specific quirks baked into a function in 2009.
Watch out for these failure modes:
- Behavioral drift in refactors. A rewritten function that looks cleaner may handle edge cases differently. Your tests need to catch this—which is why you write them first.
- Over-modernizing. AI will suggest design patterns that are technically correct but unnecessary. Resist the urge to accept every suggestion. The goal is a working upgrade, not a showcase.
- Hallucinated APIs. When asked to migrate to a new framework version, models sometimes reference methods that don't exist in that version. Always verify against official documentation.
The engineers getting the most value from AI on legacy work are the ones who treat the model as a fast but fallible collaborator—they verify its output, don't outsource their judgment, and use it to move faster on the work they understand.