← Back

December 12, 2025

When to Rewrite vs. Refactor: A Decision Framework

The rewrite-vs-refactor question comes up in every legacy modernization. Here is my thoughts based on experience modernizing legacy code.

Architecture Legacy Modernization Technical Debt

The question comes up in almost every legacy modernization engagement: should we rewrite this, or can we refactor our way out?

There’s no universal answer, but I’ve developed a framework over 20 years of making this call.

The Decision Factors

Four things determine whether refactoring or rewriting makes sense:

Code quality vs. business value. Bad code that delivers value is different from bad code that’s actively blocking the business. A messy but stable billing system might need gentle refactoring. A brittle integration layer that fails twice a week might need replacing.

Team knowledge. If the people who wrote the code are gone and documentation is sparse, we’re essentially reverse-engineering. That changes the calculus. Refactoring code we don’t understand is risky. Rewriting what we don’t understand is also risky, but at least we control the outcome.

Time and budget. Rewrites take longer than anyone estimates. Refactoring takes longer too, but the cost is spread over time. If we have 18 months and budget for a dedicated team, rewriting is an option. If we need incremental improvement while keeping the lights on, refactoring wins.

Risk tolerance. Rewrites fail more often than refactors. The second system effect is real.1 But refactoring can also drag on forever without delivering meaningful improvement. We need to be honest about our organization’s appetite for each type of risk.

When to Refactor

Refactoring is the right choice when:

  • The architecture is fundamentally sound but the code is messy
  • We can isolate changes and deploy incrementally
  • The team understands the existing system well enough to modify it safely
  • Business continuity requirements mean we can’t afford a parallel system
  • The core domain model is correct — it’s just the implementation that’s rough

The tell-tale sign: we can describe what we want to keep and what we want to change. We’re not starting from zero.

When to Rewrite

Rewriting makes sense when:

  • The architecture itself is the problem, not just the code
  • Technology constraints make the current system unmaintainable (dead language, no developers available, vendor no longer exists)
  • The requirements have changed so fundamentally that we’re fighting the original design at every turn
  • We’ve tried refactoring multiple times and it keeps failing
  • The security or compliance situation is unrecoverable without a clean slate

The tell-tale sign: every change requires fighting the system. We spend more time working around the architecture than working with it.

The Hybrid Approach

Most successful modernizations aren’t pure refactors or pure rewrites. They’re strangler fig implementations.2

The strangler fig pattern: we build new functionality in a new system while the old system keeps running. We route traffic incrementally to the new system as features become ready. The old system shrinks over time until we can finally turn it off.

This gives us the benefits of both approaches:

  • New code without legacy constraints
  • Incremental delivery without big-bang risk
  • Time to learn from early modules before committing fully

The key is having a clear interface where we can intercept and route requests. If the old system is too monolithic for this, we might need to refactor just enough to enable the strangler pattern.

Common Mistakes

Underestimating the rewrite. We almost always forget something. Hidden business rules, edge cases discovered through years of production fixes, integrations we didn’t document. Budget for discovery.

Refactoring without a target. Refactoring needs a clear end state.3 “Make the code better” isn’t a goal. “Extract the pricing logic into a testable module” is a goal. Without this, refactoring becomes an endless project.

Letting politics drive the decision. New developers want to rewrite. Developers who built the original system want to refactor. Neither perspective is objective. We need to evaluate based on the factors above, not on who shouts loudest.

Ignoring the organizational context. A rewrite requires sustained focus and executive support. A refactoring effort requires teams to accept slower feature velocity. If the organization can’t support either approach, the technical decision is irrelevant.

The Framework in Practice

When I evaluate a rewrite-vs-refactor decision, I score each factor:

  1. Is the architecture sound? (Yes = refactor, No = rewrite)
  2. Does the team understand the system? (Yes = refactor, No = consider rewrite)
  3. Can we deliver incrementally? (Yes = refactor or strangler, No = rewrite risk increases)
  4. How critical is continuity? (High = refactor, Low = rewrite is more viable)
  5. Have we already tried refactoring? (Yes, multiple times = consider rewrite)

Three or more pointing toward rewrite means we should seriously consider it. But even then, we look for a hybrid approach first.

References

  1. Brooks, F. — The Mythical Man-Month (1975)
  2. Fowler, M. — Strangler Fig Application (2004)
  3. Fowler, M. — Refactoring: Improving the Design of Existing Code (2018)