Rescue your software
Two Rewrites Over Several Years: When Rebuilding a Mobile App Is the Right Call
A bilingual travel app we maintain was rewritten twice as its scope grew. How to tell a justified rewrite from an expensive mistake.
MindForge Engineering3 min read
We usually argue against rewrites. When a client arrives with a struggling codebase, the first move is almost always to stabilise it, fix what is broken and improve it in place. Yet one of the longest-running products in our library, a bilingual tourist attractions discovery app, has been through two full architectural rewrites over several years, and it is still actively maintained and receiving new feature work. This post is about how to tell those rewrites apart from the ones that go badly.
The product
The app helps travellers discover attractions:
- Browsing runs from country to city to attraction, with suggested travel routes.
- Users save favourites.
- It is fully localised in Arabic and English, with right-to-left support.
- It supports dark mode and push notifications.
It is built with React Native and TypeScript on mobile, a Laravel backend, and Firebase Cloud Messaging for notifications. It is a multi-year, actively maintained product that is still receiving client-requested feature work.
Why rewrites usually fail
The case against rewrites is well known among engineers, and it holds up:
- The old code contains years of fixes for real problems, many undocumented. A rewrite throws them away and rediscovers them one bug at a time.
- While the rewrite happens, the existing product stops improving, or two versions have to be maintained.
- Rewrites are almost always underestimated, because the full behaviour of the old system is larger than anyone remembers.
That is why we treat stabilisation as the default. Our posts on fixing strict-mode failures in legacy PHP and moving uploads to object storage are examples of improving systems in place.
When a rewrite is justified
The tourism app's two rewrites happened to keep pace with growing scope. That is the key distinction. A justified rewrite is driven by where the product needs to go, not by dissatisfaction with where the code is.
These are the conditions we look for before recommending one:
The architecture blocks the next stage
Messy code can be cleaned up in place. An architecture that cannot support what the product now needs, such as a new navigation model, offline behaviour or a different data model, often cannot. When every new feature fights the structure, the structure is the problem.
The new scope can be described
"The code is hard to work with" is not a scope. "The app must support country, city and attraction hierarchies with routes, in two languages and both text directions" is. A rewrite needs a target clear enough to know when it is finished.
The product can keep shipping
The safest rewrites keep users served throughout, either by rewriting part by part behind the existing app, or by keeping the current version maintained until the new one is ready. A rewrite that pauses a live product for months carries the most risk.
Prototypes are not rewrites
A related pattern appears in our home services marketplace, which went through several earlier technical prototypes before converging on its current architecture. That is a different thing: exploring options before committing is cheap compared with rewriting a product that customers already depend on. The marketplace has since become a multi-year, actively maintained product, with continued backend investment well beyond its initial mobile release.
The lesson is to do your exploring early, when it is cheap, as we describe in testing two architectures in parallel.
A rewrite decision checklist
- Have we tried stabilising and improving the current code?
- Is the blocker the architecture, or just the code quality?
- Can we describe the new scope clearly enough to know when we are done?
- Can users keep getting updates during the rewrite?
- Have we listed what the old system does, including the undocumented fixes?
If the answers point to a rewrite, plan it as a project with a defined scope. If they do not, invest in the existing product. You can read the anonymised write-ups for the tourism app and the home services marketplace. Deciding between repair and rebuild is the first step in our software rescue service.
Client details in this post are anonymised to respect confidentiality. The engineering described is from the project listed below.