Developers love greenfield projects. Starting fresh means no legacy constraints, no inherited problems, no code written by someone else. The promise of a clean slate is appealing.
That promise is usually a trap.
The rebuild trap
Rebuilds fail for predictable reasons:
Scope expands - the rebuild becomes an opportunity to add features, changing the project fundamentally
Timeline extends - what was estimated at months becomes years
Old system accumulates more changes - the target keeps moving
Business logic is misunderstood - edge cases discovered in the old code are forgotten until users complain
Budget runs out - the rebuild is abandoned, leaving two broken systems
The old code, for all its problems, has been tested by real usage. It handles edge cases that nobody documented. A rebuild loses that accumulated knowledge. This is one of the key reasons websites fail after launch when original developers move on.
When rebuilding makes sense
Sometimes a rebuild is genuinely the right choice:
The technology is obsolete - framework no longer maintained, dependencies unsupportable
Requirements have fundamentally changed - the system needs to do something entirely different
Security cannot be remediated - architectural flaws that cannot be patched
The codebase is small - less accumulated logic to recreate
These situations are rarer than they seem. The frustration of working with difficult code often disguises itself as technical necessity.
The case for refactoring
Refactoring is about making the code cleaner without changing how it works. Incremental refactoring:
Preserves working functionality - users continue using the system
Delivers value continuously - each improvement is deployed
Can be stopped at any point - partial refactoring still has value
Learns from the existing code - edge cases are preserved
Carries lower risk - small changes are easier to verify
Refactoring is less exciting than a rebuild. It is also more likely to succeed.
How to approach refactoring
Effective refactoring follows a pattern:
Add tests to the existing code - verify current behaviour before changing it
Identify the worst areas - focus effort where it matters most
Make small changes - each change should be reversible
Verify after each change - run tests, check behaviour
Deploy frequently - get changes into production to confirm they work
This approach is slower than a greenfield rebuild would be in theory. It is faster than a rebuild would be in practice.
The strangler fig pattern
When significant change is needed, the strangler fig pattern offers a middle path. New functionality is built alongside the old system. Traffic is gradually redirected. The old system is eventually retired.
This approach:
Keeps the old system running during transition
Allows new components to be deployed incrementally
Provides rollback capability at each stage
Discovers integration issues early
It requires discipline to avoid running parallel systems indefinitely, but it reduces the all-or-nothing risk of a rebuild.
Making the decision
Questions to ask before deciding:
Can the existing code be tested? If yes, refactoring is possible.
Are the problems localised or pervasive? Localised problems can be refactored incrementally.
Is the technology still supported? Unsupported technology may force a rebuild.
What is the budget and timeline? Rebuilds typically cost more and take longer than estimated.
What happens if the project is stopped halfway? Partial refactoring leaves a better system. Partial rebuild leaves two broken ones.
The default should be refactoring. A rebuild should require strong justification, not just frustration. Whichever path you choose, ongoing maintenance prevents the problems that make future decisions harder.
The first step in making this decision is knowing what is actually in the site. A site health report gives you that information in plain English, within 5 working days, so you can decide with full information rather than guesswork. See what it covers.
Not sure whether to rebuild or refactor?
I can help you work out which approach fits your situation.
Get in touch