Unico Connect
Rebuild vs refactor decision framework and scorecard for founders
Back to Blog
EngineeringJuly 6, 202616 min read

Rebuild vs Refactor, How to Decide

Vasim Gujrati

Vasim Gujrati

Solutions Architect, AI & Platforms, Unico Connect

In this article

Every growing product reaches the moment where someone says the codebase is holding us back and we should just rewrite it. Sometimes they are right. Far more often a rewrite is the most expensive mistake a team can make. What follows is the framework engineers use to make that call, and a scorecard you can fill in for your own product.

Quick Answer

Refactor by default, and rebuild only when the foundation itself is wrong. Refactoring improves the code you have in small, safe steps without changing what the software does. A rebuild throws that away and starts over, which forfeits years of accumulated bug fixes and hard won knowledge. The evidence is clear that big bang rewrites aimed at feature parity usually fail, while those that run in parallel or replace the old system piece by piece tend to succeed. When the answer falls somewhere in between, the strangler fig pattern lets you replace an old system gradually while it keeps running.

What is the difference between refactoring and rebuilding?

One improves the code you already have and the other replaces it. Refactoring, as Martin Fowler defines it, changes the internal structure of code without changing its observable behaviour, done in small steps each backed by tests. The software does the same thing as before, only cleaner inside. A rebuild or rewrite replaces the code and usually changes the architecture and behaviour along the way. So refactoring is low risk and continuous, while a rebuild is a large bet that the new version will be better than the one you already shipped.

Why does Joel Spolsky call a full rewrite the single worst strategic mistake?

In his 2000 essay Things You Should Never Do, Joel Spolsky argued that throwing away a working codebase and starting from scratch is the single worst strategic mistake that any software company can make. His reasoning still holds up. Code is harder to read than to write, so old code looks worse than it is. The ugly parts are often accumulated fixes, each encoding a real bug someone hit in the field, and a rewrite quietly discards all of them. Software does not rot on its own. While you spend two or three years rebuilding what you already had, your competitors keep shipping. The classic cautionary tale is Netscape, a company that handed away its lead by rewriting its browser and starting over.

If rewrites are so dangerous, why do some of them succeed?

The ones that succeed are not big bang rewrites. When Herb Caudill studied six well known software rewrites, the pattern was consistent. The rewrites that worked ran the new product alongside the old one, or targeted a market the old product could never serve, and never switched everything off overnight. The ones that failed tried to rebuild the whole thing to feature parity and flip a switch. Fred Brooks named the trap decades ago as the second system effect, where the ambitious successor collapses under every feature the first version wisely left out. A rewrite can still be the right call, but one that stops the world to reach parity almost never is.

The winners tend to follow one of two shapes. The first is a parallel product rather than an in place replacement. Microsoft kept Visual Studio and built Visual Studio Code as a new lightweight editor alongside it, and that new product went on to lead its market. Basecamp rewrote its app but kept the old versions running for existing customers instead of forcing everyone across on a launch date. The second shape is building something the old product structurally could not become. Instead of rewriting its bug tracker FogBugz, Fog Creek built the new horizontal product Trello, which grew past 19 million registered users and was acquired by Atlassian for around 425 million dollars in January 2017. If you are a founder weighing a rewrite, copy these shapes. Run the new thing in parallel and keep the old one alive until the new one is proven, and never turn the business off to chase feature parity.

When does refactoring in place win?

Refactoring wins when the foundation is sound and the pain is local. If the architecture still fits where the business is going, the people who know the code are still around and the problems sit in messy modules rather than a broken core, you can almost always improve your way out in small steps while you keep shipping. Improving in place is the default because it carries the least risk and never stops delivery, and the knowledge baked into the existing system survives the change.

When is a rebuild actually the right call?

A rebuild earns its risk when the foundation itself is the problem. The signals worth taking seriously are a data model or architecture that fights every new feature, a platform or stack that is at end of life or cannot be hired for, a no-code or AI generated base that has hit a hard ceiling on control, cost, or compliance, and a codebase nobody understands because the people who wrote it are gone and there are no tests. When several of these are true at once, incremental change stops paying off and a planned replacement becomes the cheaper path. Even then, plan it as a phased replacement and avoid a big bang cutover.

How do you rewrite without a big bang cutover?

You use the strangler fig pattern, described by Martin Fowler and endorsed in both Microsoft Azure and AWS architecture guidance. You put a facade in front of the old system, then build the new system behind it one capability at a time. Traffic for each migrated feature routes to the new code while everything else keeps hitting the old system, and you delete the old parts only once the new ones are proven. The product stays live the entire time, risk is spread across many small cutovers instead of one terrifying launch, and you can stop or reverse at any point. Its in codebase cousin, branch by abstraction, does the same thing for a module inside a single application.

In practice the mechanics matter as much as the pattern. Cut the work into thin vertical slices that each still deliver something a user or the business can see, rather than rebuilding a whole layer before anything ships. Where you can, run the old and new paths in parallel for a while and compare their outputs, so you catch a difference before customers do. Shift real traffic gradually, a small percentage first, then more, watching the error rate at each step, so a problem shows up at five percent of users rather than all of them. Give the new service its own data and keep the two in sync during the transition. Every slice also needs its own rollback path, so any single cutover can be reversed on its own. Together these steps keep a replacement boring, which is what you want from one.

Can you rewrite just one part instead of the whole thing?

Usually yes, and it is the option founders forget. Between rebuild and refactor sits a middle ground the industry calls rearchitecting or replatforming. You can lift one painful module onto a new foundation while leaving the rest alone, move a workload to managed infrastructure without rewriting its logic, or use the strangler fig pattern to replace the single hot part of the system that causes most of the pain. Most of the time the honest answer to should we rebuild is rebuild the one part that is broken, and refactor the rest. Saving the full ground up rebuild for the rare case where the entire foundation is wrong keeps the risk proportional to the problem.

How do you measure technical debt before you decide?

Pull a few numbers before anyone argues from opinion, because a rebuild decision made on gut feel is how teams talk themselves into the expensive mistake. Three measures do most of the work. The technical debt ratio, from the SQALE method, expresses the cost to fix the code as a percentage of the cost to build it, and a ratio creeping past roughly twenty percent is a signal that the debt is systemic rather than local. Code churn, how often the same files are rewritten between releases, points at the unstable areas that a rebuild would need to get right. Defect density, the rate of bugs in a given area, shows where the code is failing users rather than merely looking untidy. Static analysis of cyclomatic complexity and duplication rounds out the picture. None of these decides for you. Together they turn a shouting match into a conversation about evidence and tell you whether the problem is one module or the whole foundation.

Why do AI built and no-code MVPs hit this wall so fast?

Tools like Lovable, Bolt, v0, Cursor, and Bubble get a product in front of users remarkably fast, and that speed is real value. They also pile up debt quietly. Business rules get duplicated across screens, authentication becomes code nobody dares touch, the data model starts fighting every new feature, and no-code platforms hit performance and pricing ceilings that only show up at scale. Industry reports suggest AI generated code carries meaningfully higher defect and vulnerability rates than hand written code, though the exact multipliers vary by study and should be treated as directional rather than precise. The wall is usually hidden debt rather than a bad tool, so base the rebuild call on the signals below and resist a reflex against no-code.

How do you score your own codebase?

Give each factor a score from 1 to 5. Score it a 1 when your situation looks like the middle column, which leans toward refactoring, and a 5 when it looks like the right column, which leans toward a rebuild. Use 2 to 4 for anything in between, then add the scores up. The bands below are a guide and do not make the call for you.

FactorScore 1, leans refactorScore 5, leans rebuild
Business model fitStill serves the businessBuilt for a dead model or one lost customer
Tech debt severityIsolated, messy areasSystemic and actively blocking the business
Change velocity trendFeature time is predictableVelocity drops monthly, changes ripple everywhere
Architecture fitAbsorbs where you are goingFundamental mismatch, wrong data model
Test and safety netMeaningful tests existNone, you cannot change anything safely
Team and tribal knowledgeAuthors still aroundGone, nobody understands the code
Platform viabilityMainstream and hireableNo-code ceiling, dead stack, or unmaintainable AI code
Security and data integrityHandled deliberatelyBolted on, with known vulnerabilities
Capacity to do itCan only improve incrementallyYou have the budget, team, and time for a phased rebuild
Migration feasibilityIncremental cutover works cleanlyStanding still is riskier than moving

A total of roughly 10 to 20 points means refactor in place. Around 21 to 35 points to incremental replacement with the strangler fig pattern, and around 36 to 50 means a phased rebuild is worth planning. Beyond the score, the single most useful question to ask is a simple one. If we keep building on this for six more months, what gets easier and what gets harder?

How do you explain a rebuild decision to stakeholders?

Frame it in business terms. What a board or an investor cares about is that shipping the next three features will take twice as long and cost twice as much on the current foundation. They do not care that the cyclomatic complexity is high. Lead with the conclusion and one number that matters, such as the months of runway the decision buys or the feature velocity it restores, then show the total cost and the payback period, and tie it to revenue or risk rather than code quality. Spell out the safe path, namely that you will keep the product live and migrate incrementally instead of stopping the world. That answers the fear a stakeholder has about the word rebuild, which is the Netscape story whether or not they can name it. The scorecard helps here too, because a tallied score reads as a considered decision rather than an engineer wanting to start over.

Frequently Asked Questions

Is it ever a good idea to rewrite software from scratch?

Yes, but rarely as a big bang. Rewrites that run in parallel with the old product or replace it incrementally tend to succeed. Trying to rebuild everything to feature parity and switch over in one launch tends to fail, and that is the Netscape pattern Joel Spolsky warned about.

What is the difference between refactoring and rewriting?

Refactoring improves the internal structure of code without changing what it does, in small steps backed by tests. Rewriting replaces the code and usually changes its behaviour and architecture too. The first is continuous and low risk, while the second is a large bet.

What is the strangler fig pattern?

It is an incremental replacement strategy. You put a facade in front of the old system and rebuild it one capability at a time behind that facade, routing traffic to each new piece as it is proven, until the old system can be deleted. The product stays live throughout, so risk is spread across many small cutovers.

My MVP was built with Lovable or Bubble and it is breaking. Do I rebuild?

Not automatically. Rebuild only if the data model or security has failed, or if every change now sets off ripple effects across the product. If the real problem is product direction rather than code, redesign first. Often the right move is to refactor the worst parts or migrate them incrementally rather than start over.

How much riskier is AI generated code?

Industry reports suggest it carries higher defect and vulnerability rates than hand written code, but the specific numbers vary widely between studies, so treat them as directional. The bigger practical risk is hidden debt such as duplicated logic and untested authentication rather than any single headline figure.

How do I decide without going on gut feel?

Score the ten factors in the scorecard above from 1 to 5 and add them up. A low total points to refactoring, a middle total to incremental replacement with the strangler fig pattern, and a high total to a planned phased rebuild.

Can I rewrite just one part of my application?

Usually yes, and it is often the right answer. You can rearchitect or replatform a single painful module, or use the strangler fig pattern to replace the one hot part of the system that causes most of the pain, while refactoring the rest. Reserve a full ground up rebuild for the rare case where the whole foundation is wrong.

How do I measure technical debt before deciding?

Pull three numbers first. The technical debt ratio is the cost to fix expressed as a percentage of the cost to build, and a ratio past roughly twenty percent signals systemic debt. Code churn, how often the same files are rewritten, shows the unstable areas, and defect density shows where the code fails users. Together they tell you whether the problem is one module or the whole foundation.

How do I explain a rebuild to investors or stakeholders?

Lead with the business conclusion and one number that matters, such as restored feature velocity or runway, show the cost and payback, and tie it to revenue or risk rather than code quality. Make clear you will keep the product live and migrate incrementally, because the real fear behind the word rebuild is a company going quiet for two years.

Where Unico Connect fits

We help you make the call and then carry out a safe migration while the business keeps running. If you are weighing this call on an MVP that outgrew its foundation, or on an app built with Lovable or another no-code stack, we audit the real state first, then either refactor in place or run a strangler fig migration onto a system you own. If you inherited the code and do not yet know what you have, start with our guide on taking over an existing codebase.

Keep reading

Latest Blogs & Articles

View all