Rewrite or Refactor? A Decision Guide for Non-Technical Founders

Nitheesh KR
CEO @ Playxoft
•8 min read
Legacy SystemsRefactoringEngineeringTechnical Debt
Two paths from an ageing codebase, one a full rewrite and one incremental replacement

At some point, a developer will tell you the system needs to be rewritten. They will be sincere. They may well be right. And you, not being technical, have no way to tell the difference between a genuine engineering judgement and an understandable human preference for starting fresh.

This is one of the most expensive decisions a software business makes, and it is routinely made on instinct.

The rewrite vs refactor question for legacy software is not really a technical question. It is a risk question, and risk is something you are already qualified to reason about. What follows is how to think it through without needing to read the code.

First, understand what each word actually means

Refactoring means improving the code's structure without changing what it does. The product keeps running the whole time. Users notice nothing. You ship small improvements continuously alongside normal feature work.

Rewriting means building a replacement system from scratch, then switching over. For the duration, you are maintaining the old system while building the new one, and delivering no new value from either.

That last sentence is the whole risk, and it deserves to be sat with. During a rewrite, your competitors keep shipping. Your customers keep asking for things. Your team is working hard and your product is standing still.

Why engineers reach for the rewrite

It is worth understanding the instinct rather than dismissing it, because it comes from somewhere real.

Reading unfamiliar code is genuinely harder than writing new code. Every developer has experienced opening a file, failing to understand why something works the way it does, and feeling certain they could do better. Sometimes they could.

But the thing that makes old code ugly is often the thing that makes it correct. Those strange conditionals usually encode a bug someone hit in production at two in the morning. That awkward special case is probably a customer who threatened to leave. A rewrite discards all of it, and then rediscovers it, one incident at a time, over the following year.

Joel Spolsky's essay on why rewriting from scratch is the single worst strategic mistake is twenty-five years old and has aged remarkably well. It is worth reading before you approve one.

Two paths from an ageing codebase, one a full rewrite and one incremental replacement

The five questions that usually settle it

Ask these, in this order. You do not need technical knowledge to evaluate the answers.

Can we ship features today, at an acceptable pace? If the answer is yes, even if it is slower than you would like, you almost certainly want to refactor. Working software that ships slowly beats no software that ships perfectly.

Is the problem the code, or the platform underneath it? These get conflated constantly. Code that is messy but running on a supported platform can be improved in place. Code running on something that no longer receives security updates, or that nobody in the market still knows how to hire for, is a different and more urgent problem.

Do we understand what the current system does? If nobody on your team can explain the business rules the old system enforces, a rewrite will not reproduce them. You will ship something that is subtly wrong in ways you discover from customer complaints.

What is the cost of being frozen for the duration? Be specific and honest. If a rewrite takes eight months — and it will take longer than the estimate — what deals do you lose, what customers churn, what competitor gains ground?

Is there a forcing event? A platform reaching end of life, a compliance requirement, an acquisition, a licensing change. A real external deadline sometimes makes a rewrite the rational choice even when it would otherwise not be.

The honest answer for most businesses

For the large majority of situations we are asked about, the answer is: refactor, and do it continuously rather than as a project.

That means fixing structure as you touch things, adding tests around the parts you are about to change, extracting the worst-understood areas into something comprehensible, and improving the pieces that hurt most. It is unglamorous and it never produces a celebratory moment, which is precisely why it gets skipped.

The compounding effect is real though. A team that leaves each file slightly better than they found it has a materially different codebase a year later, without ever having stopped shipping.

If you are being asked to approve a rewrite

Before you sign off, ask for three things in writing: what specifically cannot be fixed incrementally and why, what the plan is for the months when no new features ship, and what happens if the estimate doubles.

If those answers are thin, we are happy to give you a second opinion — an outside read from people with no stake in which answer is right. Sometimes it confirms the rewrite. Often it finds a narrower fix.

The middle path almost nobody proposes

There is a third option, and it is usually the correct one for systems too far gone to refactor comfortably but too valuable to switch off.

It is called the strangler pattern, named after a vine that grows around a tree and gradually replaces it. Instead of rebuilding everything and switching over on one terrifying day, you put a routing layer in front of the old system, then replace one piece at a time behind it. Each piece goes live as it is finished. The old system shrinks. Eventually nothing is left of it.

Martin Fowler's description of the strangler fig application explains the mechanics well. The advantages that matter to you as a founder:

  • You ship value continuously instead of disappearing for months
  • Each step is independently reversible if something goes wrong
  • You can stop at any point and still be better off than when you started
  • The team learns the old system's actual behaviour gradually, instead of guessing at it all at once

The trade-off is real: for a period you run two systems, which adds operational complexity and requires discipline about what goes where. Done without a plan, you end up permanently half-migrated, which is worse than either pure option.

How to tell if a rewrite is going badly

If you do proceed, watch for three signals:

The estimate moves more than once. A single revision is normal. A second one means the team is discovering the old system's real behaviour as they go, and there is no reason to think the third estimate will hold either.

Feature parity keeps receding. "We just need to add a few more things before we can switch" is the sound of a rewrite that has found the long tail of edge cases. That tail is usually longer than everything that came before it.

The old system is still getting changes. If you are patching the thing you are replacing, you are now maintaining two systems and the new one is chasing a moving target.

Any of these is a reasonable moment to stop and convert to an incremental approach. Sunk cost is not a reason to continue, and a partially built new system can often become the first step of a strangler migration rather than a write-off.

Checklist of modernisation choices that reduce risk and ones that increase it

What this looks like in practice

A typical engagement we take on starts with someone convinced they need a rewrite. We spend a few days reading the system and talking to whoever has been maintaining it. Roughly speaking, the outcomes split three ways.

Sometimes the code is fine and the real problem is that nobody has written down how it works, so every change feels dangerous. Documentation and a test suite fix that, at a fraction of the cost.

Sometimes one specific part — usually the oldest, most-patched module — is genuinely beyond repair while the rest is serviceable. Replacing that one piece behind a facade solves the actual pain.

Occasionally the platform really is dead, the original team is long gone, and a rewrite is the honest answer. It happens. It is just far rarer than the number of times it gets proposed.

What to ask your team before deciding

Three questions that surface the real situation faster than a technical review:

"Which part of the system are you most afraid to change?" The honest answer points at the module that genuinely needs work. It is rarely the whole thing. Most systems have one or two areas that everyone routes around, and the rest is merely untidy.

"If we gave you one month and no new features, what would you fix?" This separates engineers who have a specific plan from ones who have a general feeling. A specific answer is a refactoring plan you can fund. A vague answer means more investigation is needed before any decision.

"What would break if we changed this tomorrow?" If nobody can say, that is the actual problem — not the code quality, but the absence of tests and documentation that would let anyone answer confidently. Fixing that is cheaper than either a rewrite or a large refactor, and it makes both of those safer later.

Choose the option you can stop

If you take one principle from this: prefer the path you can abandon halfway through and still be better off.

Refactoring passes that test. The strangler pattern passes it. A full rewrite does not — stop it at sixty percent and you have nothing but a bill and a year you cannot get back.

That asymmetry, more than any technical argument about the code, is why the rewrite vs refactor decision for legacy software should start from risk rather than from preference.

If you are facing this decision and want an outside opinion from people who will tell you when a rewrite is genuinely justified — and when it is not — book a free consultation call or email nitheesh@playxoft.com. We will read the system first and give you an answer with reasons attached.

Nitheesh KR

Nitheesh KR

CEO @ Playxoft