Skip to Content

Legacy Code

Legacy code is existing software that is difficult to modify, extend, or understand. Often, it lacks tests, documentation, or the original developers have moved on. Contrary to popular belief, legacy code isn't inherently bad. It represents software that has delivered value long enough to become entrenched. The challenge lies in evolving it safely.

Key Statistics

Why This Matters

Almost every professional developer works with legacy code at some point in their career. Whether it's a decade-old monolith or a two-year-old codebase written by a team that has since departed, the skills required to understand, modify, and improve existing code are essential.

The most successful approaches to legacy code focus on incremental improvement rather than wholesale replacement. Techniques like the Strangler Fig pattern, characterization testing, and strategic refactoring allow teams to evolve systems safely while continuing to deliver business value.

On the Maintainable Software Podcast, guests have shared hard-won wisdom about navigating legacy codebases. Michael Feathers talks about getting legacy code under test. DHH shares his perspective on celebrating legacy software as a victory. And many more.

Episodes on Legacy Code

Frequently Asked Questions

What is legacy code?

Legacy code is generally defined as existing code that is difficult to change safely. Michael Feathers famously defined it as code without tests. More broadly, it includes any codebase where the original context, documentation, or developers are no longer available, making modifications risky and time-consuming.

How do you modernize legacy code without rewriting it?

The most effective approach is incremental modernization using patterns like the Strangler Fig, where new functionality gradually replaces old components. Start by adding characterization tests to understand existing behavior, then refactor in small steps. This reduces risk compared to full rewrites while delivering continuous improvements.

What are the risks of working with legacy code?

Key risks include introducing regressions due to lack of test coverage, misunderstanding business logic embedded in the code, underestimating the complexity of dependencies, and developer burnout from working in frustrating codebases. Mitigate these through incremental testing, documentation, and pair programming.

How do you add tests to legacy code?

Start with characterization tests that capture the code's current behavior, even if that behavior includes bugs. Use Michael Feathers' 'seam' technique to find points where you can alter behavior without changing the code. Focus testing efforts on the areas you plan to modify first, then expand coverage incrementally.

When should you rewrite vs. refactor legacy code?

Rewriting is rarely the right answer. Studies show 60-80% of rewrite projects fail. Refactoring is safer and delivers value incrementally. Consider rewriting only when the technology stack is completely obsolete, the codebase is very small, or the business requirements have changed so fundamentally that the existing architecture can't support them.

Related Topics

Between the episodes

223 Episodes published since 2019

Stay sharp. Skip the noise.

One email when a new episode drops. That's it.

Joined by engineering leaders at companies you've heard of.