Two very different projects
Refactoring changes the structure of existing code without changing what users see. You clean up one area, add tests, split a tangled module, upgrade a library. The app keeps running throughout.
Rebuilding means writing a new application, then moving users and data across to it.
A rebuild is tempting. Old code is frustrating, and a fresh start sounds clean. But a rebuild spends a lot of money getting back to where you already are before it adds anything new. The decision deserves more than a developer’s irritation with the codebase.
Take stock first
Get answers to these before anyone recommends either path.
- Do you have the source code and access to the repository? If a previous vendor holds it, getting it comes first.
- Can someone new deploy the app? If releases depend on one person’s memory, write the process down.
- Are there automated tests? Tests make refactoring safer; without them, every change is a gamble.
- Does the data model still match the business? An app built for one branch that now serves twelve, or for one unit per product when you now sell by the piece, box and carton, has a foundation problem.
- Is the framework and language version still supported? Software past end of life stops getting security fixes. AngularJS, for example, reached end of life years ago, and very old PHP versions no longer get fixes.
- Is the pain in a few areas, or everywhere?
- What does the business need next (mobile access, more branches, integrations, AI features), and can the current app take it?
When refactoring is enough
Users rely on the app and it mostly does the job. The data model is right, even if the code around it is messy. Problems cluster in a handful of areas. The framework is supported, or can be upgraded in steps. A developer new to the code can follow a feature with some effort. And what the business needs next extends what already exists.
If that describes your app, improve it in place.
When a rebuild is worth considering
- The framework or language version is unsupported, and upgrading means rewriting most of it anyway.
- The data model fights the business, and changing it touches every screen.
- Fixing one thing regularly breaks something unrelated.
- The same kind of bug appears in many places, because logic was copied instead of shared.
- Nobody can explain how important parts work, and the people who wrote them have left.
- The business needs something the app can’t do, such as a web version of desktop software.
One sign alone rarely justifies a rebuild. Several together, especially an unsupported platform plus a data model that no longer fits, usually do.
Find what the old app does quietly
Old apps do things nobody recalls deciding. A report rounds figures a particular way. An email goes to the accountant at month end. A sales order stops when a customer is over their credit limit. Staff depend on these without knowing they exist, and a rebuild that misses them breaks the business in small ways after launch.
So before a rebuild, list every screen, report, scheduled job, email and integration in the old app. Sit with the people who use it daily and note what they actually do. Keep copies of real outputs (invoices, reports, exports) to compare against the new system.
Watch for the second-system effect, which Fred Brooks described in The Mythical Man-Month: the replacement gets loaded with every feature postponed the first time. Scope the rebuild as a replacement. Improvements come after.
The middle path: replace it piece by piece
Martin Fowler named this the strangler fig pattern. Instead of switching everything on one day, you build new parts alongside the old app and move one area at a time.
- Put a layer in front of the old app that can send each request to the old or the new system.
- Rebuild one area, such as customer onboarding or invoicing.
- Switch that area over, and run both for a while.
- Repeat until nothing is left in the old app, then retire it.
The business keeps running while the old app is replaced. The tricky part is data shared between old and new parts, which needs careful handling.
Moving the data
In most rebuilds, the data move is the hardest part. Map old fields to new ones, decide what to clean, and run test migrations on a copy of real data well before launch. If the old data model was the problem, this is where it shows. Our PostgreSQL guide covers what to get right in the new one.
Questions for a team recommending a rebuild
- What exactly can’t be fixed in the current app, and why?
- What would a refactor-first plan look like?
- How will you find everything the old app does?
- How will the data move, and how will you check it moved correctly?
- Can the replacement happen in stages?
- What happens to daily operations during the switch?
How we’d approach it
Either way, Microsive starts with a written scope and fixed quote (how we work). Our web app page describes the kind of software we rebuild and extend. The source code and repository are yours.
Before we touch a data model or run a migration, we restore the backup first and work against the restored copy. The restore proves the backup is real, and it gives us the same data to try the change on before it goes anywhere near the live app.