To production
Rewrite or refactor: the question is what you can still change
Reviewed September 2026
01
What each word actually means
The two get used loosely, which is how teams end up arguing past each other. They're precise terms. Refactoring means changing the internal structure of code without changing what it does — you keep the behaviour and improve the shape, in small, reversible steps, with tests catching you if you break something. It's maintenance, done continuously or in a focused push.
A rewrite is the opposite bet: you set the existing implementation aside and build it again, often on a new stack. The product's behaviour is the target, but the code is new. Refactoring is renovating the house room by room while you live in it; rewriting is building a new house and moving. The right choice isn't a matter of taste — it depends almost entirely on what you're still able to change in what you have.
- Refactor. Change structure, keep behaviour, move in small safe steps. Requires code you can open, test and evolve.
- Rewrite. Rebuild the implementation, usually on a new stack. Necessary when the existing code can't be evolved — or doesn't exist as code you own.
02
The classic warning — and its limit
The default advice, and it's good advice, is: don't rewrite. In "Things You Should Never Do, Part I," Joel Spolsky called throwing away a working codebase "the single worst strategic mistake" a software company can make, using Netscape's ground-up rewrite — which cost it years and, arguably, the browser wars — as the cautionary tale. The reasoning holds up: working code contains years of accumulated bug fixes and hard-won edge-case knowledge that looks like mess and is actually experience. A rewrite throws that away and re-learns it the hard way.
But the warning assumes something specific — that you have a working codebase to keep improving. That's the hinge. If you can still change the code safely, Spolsky is right and a rewrite is usually vanity. If you can't — because the code is genuinely unmaintainable, or because there is no code, which is the reality for most no-code apps — then "never rewrite" is advice about a situation you're not in.
"Never rewrite" is advice for teams who can still refactor. If you can't open or safely change what you have, the rule doesn't apply — the decision was made for you.
Sources: [1]
03
When refactoring wins
Refactoring is the right, cheaper, lower-risk answer far more often than founders expect. If the app is built in code you own, the architecture is fundamentally sound, and the pain is localised — a slow module, a tangled corner, an area that's become scary to touch — then you improve it in place, behind tests, without betting the company on a big-bang cutover.
The tell is that you can still ship. If features are still going out, and the problem is that they're going out slower or more nervously than they used to, that's a refactoring problem. You're not trapped; you're carrying debt, and debt is paid down incrementally. Reaching for a rewrite here trades a manageable, known situation for a risky, unknown one — the exact mistake the classic warning is about.
04
When a rewrite is forced
Sometimes there's nothing to refactor, and pretending otherwise just wastes months. The clearest case is the one this whole hub is about: a no-code or AI-built app where you don't have exportable source. You cannot refactor code you can't open. Bubble states plainly there's "no way of exporting your application as code"; several other builders hand over a fragment at best. When the logic that runs your product was never portable, evolving it in place isn't an option — the only route forward is to re-implement it in code you own.
The other forced case is code so tangled that changes are no longer safe at any size — where every fix breaks two things and no one can predict the blast radius. That's rare, and it's often misdiagnosed (a hard codebase is usually refactorable; a genuinely unmaintainable one is not). But when it's real, a disciplined rewrite is the honest call. Either way, the decision was made by what you can change, not by preference.
05
How to de-risk a rewrite
If a rewrite is forced, the way to avoid Netscape's fate is to refuse the big bang. The safe pattern is incremental: keep the old system running and serving users, build the new one alongside it, and move functionality across a piece at a time — the "strangler fig" approach, where the new system gradually surrounds and replaces the old one until the original can be switched off.
For a no-code app that means the old platform keeps paying its way while you rebuild the highest-risk or highest-cost part first, migrate the data with reconciliation against the source, and cut over feature by feature with a rollback path at every step. A rewrite fails when it's a two-year rebuild in the dark that has to be perfect on launch day. It succeeds when it's a sequence of small, reversible migrations, each one live and earning before the next begins.
The decision, as three questions
Strip away the debate and the choice comes down to three questions, answered honestly about the app in front of you. First: can you open the source? For a no-code or AI app with no usable export, the answer is no — and that ends it, because you can't refactor what you can't open. Second: if you can open it, can you change it safely — are small edits still low-risk behind tests? If yes, refactor; the classic warning applies and a rewrite is probably vanity. Third: is the architecture itself the bottleneck — not a messy module, but the foundation? If the code is sound and the pain is localised, refactor. If the foundation is the constraint, or there's no code to begin with, a phased rewrite is the honest path. Two of the three roads lead to refactoring. The one that leads to a rewrite is usually the no-code one, where the decision was made the day the app was built on a platform that exports nothing.
- Can't open source
- Rewrite
- Safe to change
- Refactor
- Localised pain
- Refactor
- Foundation is the limit
- Rewrite
FAQ
Questions people actually ask.
- Should I rewrite or refactor my app?
- Refactor if you own the code, the architecture is sound, and the pain is localised — it's cheaper and far less risky. Rewrite when you can't change what you have safely, or when there's no exportable source to change, which is the reality for most no-code apps. The deciding question is whether small, safe changes are still possible today.
- Is rewriting software always a mistake?
- No, but it's the default mistake. Joel Spolsky's famous warning — using Netscape's rewrite — is right for teams who still have working code they can improve. It stops applying when the code can't be safely evolved, or when there's no code to keep, as with a no-code app. Then a disciplined, phased rewrite is the honest option, not vanity.
- Can you refactor a no-code app?
- Not in the engineering sense. Refactoring means restructuring source code, and most no-code platforms don't give you usable source — Bubble exports none at all. You can rework things inside the builder's limits, but you can't refactor code you can't open. Moving to something you can maintain means rebuilding in owned code, carrying your data across.
- How do I reduce the risk of a rewrite?
- Refuse the big bang. Keep the old system live, build the new one beside it, and migrate feature by feature — the strangler-fig pattern — with data reconciled against the source and a rollback path at each step. Rewrites fail when they must be perfect on launch day; they succeed as a sequence of small, reversible migrations that each go live before the next starts.
Sources
Every claim, traced to a primary source.
The numbered references in the body link here. We cite vendor docs, pricing pages, changelogs and named reporting — dated where the document is dated, so the page can be re-audited each quarter.
- [01]Things You Should Never Do, Part I
Joel on Software · 2000-04-06joelonsoftware.com
- [02]Application and data ownership — "no way of exporting… as code"
Bubble Docsmanual.bubble.io
Ready to make it production-grade?
We’ll map the route to code you actually own.
Book a call with Jackson, our Growth Partner — he’ll walk your export or app, the gaps that matter, and a fixed-price plan to get it production-ready, live on your screen. Or get an instant estimate first.
Or see fixed-price migration packages and how we work.