Business · 7 min read

Rescue, refactor or rewrite? How to decide what to do with an AI-built codebase

Rescue when the product works and the problems are security, configuration and missing safety nets. Refactor when it works but every change is slow and risky. Rewrite only when the data model or platform is fundamentally wrong — and even then, replace it piece by piece. The deciding factor is the data model, not how messy the code looks.

By BacklooPublished

Key takeaways

  • Messy code is not a reason to rewrite. A wrong data model, an unfit platform or untrustworthy data can be.
  • Rescue fixes what blocks a safe launch; refactor reduces the cost of future change; rewrite replaces the foundation.
  • Big-bang rewrites carry the most risk: you freeze features, maintain two systems and rediscover forgotten edge cases.
  • The strangler fig pattern lets you rewrite incrementally while the old app keeps earning.
  • Decide with evidence: a short, fixed-price audit is cheaper than guessing wrong in either direction.

Should you rescue, refactor or rewrite an AI-built app?

In most cases, rescue first. If users can complete the core flow and the data model roughly matches the business, the fastest and least risky path is to fix security, configuration and reliability in place, then refactor the parts you change most often. A rewrite is justified only when the foundation itself is wrong, and it should almost always be done incrementally.

That answer frustrates people on both sides. Founders who are tired of the AI-generated code want a clean start. Engineers who inherit it often want the same thing, because rewriting feels more productive than reading. But the code you can see is rarely the expensive part. The expensive part is the behaviour nobody wrote down — the edge cases users already rely on, the data already in production, the integrations that work for reasons nobody remembers.

66%

of developers name "AI solutions that are almost right, but not quite" as their top frustration; 45% say debugging AI code takes longer — Stack Overflow Developer Survey 2025 ↗

"Almost right" is the normal state of an AI-built app at launch. Almost right is usually fixable. The question is how much of the foundation is in the "almost".

What do rescue, refactor and rewrite actually mean?

They differ in what changes and what stays. Rescue changes the minimum needed to run safely in production. Refactor changes the internal structure without changing behaviour. Rewrite replaces the implementation, and usually the data model, while trying to preserve behaviour.

  • Rescue — close security holes (authorization, leaked secrets, unverified webhooks), fix configuration, add error monitoring, backups and tests around critical flows. The architecture stays.
  • Refactor — restructure code that slows every change: duplicate logic, components that do five things, business rules scattered between UI and database. Behaviour stays; tests prove it.
  • Rewrite — build a new implementation, often on a different data model or platform, and migrate users and data to it.
Rescue vs refactor vs rewrite
RescueRefactorRewrite
WhenCore flow works; blockers are security, config, reliabilityWorks, but each change is slow or breaks something elseData model, platform or core architecture cannot support the product
RiskLow — small, targeted changesMedium — controlled by tests and small stepsHigh — new bugs, lost edge cases, data migration, feature freeze
Cost driversNumber of security and reliability gaps; access to accounts and dataSize of the areas you change often; test coverage you have to add firstFeature surface, data migration, integrations, running two systems in parallel
TimelineDays to a few weeksOngoing, alongside feature workMonths, with the old system still in production
Users noticeFewer errors; nothing else changesNothing at first, then faster deliveryA migration, and usually some regressions

Which signals point to each option?

Look at the data model and the change history before you look at code style. Ugly components are cheap to fix. A schema that cannot represent your business is not.

Signals for a rescue

  • Users can complete the main flow end to end.
  • The tables roughly match the real-world things you sell or manage.
  • The problems you know about are security, deployment, payments, error handling or performance hot spots.
  • You can name the five flows that matter and they mostly work.

Signals for a refactor

  • Small features take days because the same logic exists in several places.
  • Fixing one bug reliably creates another nearby.
  • Most churn concentrates in a few files or modules (check git log --stat).
  • Nobody, human or AI, can change a part of the app without reading all of it.

Signals for a rewrite

  • The data model is wrong at its core — for example, single-user tables for what must be a multi-tenant product, or money stored as floats across the schema.
  • The platform cannot do what the product needs (a no-code backend that cannot run the jobs, compliance or integrations you have signed up for).
  • Data integrity cannot be trusted and cannot be repaired in place.
  • There is little real usage yet, so there is little behaviour to preserve.

What does each option really cost?

The direct cost is engineering time. The bigger cost is what that time displaces. Debt you leave in place keeps taxing every future feature; a rewrite pauses the roadmap and spends money rebuilding what already exists.

20–40%

of the value of a company's whole technology estate is tech debt; 10–20% of new-product budgets get diverted to dealing with it — McKinsey, "Tech debt: Reclaiming tech equity" ↗

That is the argument against ignoring the problem, not an argument for a rewrite. A rewrite has its own costs that are easy to underestimate:

  • Feature freeze. While the new system is being built, the old one gets only urgent fixes, and competitors keep shipping.
  • Rediscovered requirements. Every quiet edge case the old app handled has to be found again, often by users.
  • Data migration. Moving production data to a new schema needs scripts, rehearsals, validation and a rollback plan.
  • Two systems. Until the cut-over, you pay to run, monitor and secure both.

Rescue and refactor costs are easier to bound, because each change is small and can be priced and verified on its own. That is why we structure them as fixed-scope sprints rather than open-ended hourly work.

If you must rewrite, use the strangler fig pattern

The strangler fig pattern, described by Martin Fowler, replaces a system piece by piece instead of all at once. You put a routing layer in front of the existing app, build one capability in the new system, send that traffic to it, and repeat until the old system has nothing left to do. The old app keeps serving users the whole time.

  1. Put a seam in front. A reverse proxy, edge middleware or API gateway that can route by path or feature.
  2. Pick the first slice. Choose something valuable and well-bounded — often the area with the worst bugs or the most change.
  3. Build it new, with tests. Include the data it owns, and decide how data syncs with the old system during the transition.
  4. Route traffic gradually. Behind a feature flag, to internal users first, then a percentage, then everyone.
  5. Delete the old code path. A slice is finished when the old implementation is gone, not when the new one exists.
ts
// Next.js proxy (middleware) as the strangler seam:
// migrated paths go to the new service, everything else stays on the old app.
import { NextResponse, type NextRequest } from "next/server";

const MIGRATED = ["/billing", "/api/invoices"];

export function proxy(req: NextRequest) {
  const path = req.nextUrl.pathname;
  if (MIGRATED.some((p) => path === p || path.startsWith(p + "/"))) {
    return NextResponse.rewrite(new URL(path + req.nextUrl.search, process.env.NEW_SERVICE_URL));
  }
  return NextResponse.next();
}

The routing is the easy part. The hard part is data. While both systems run, each piece of data needs exactly one owner: either the new service reads and writes it and the old app goes through the new service, or the old database stays the source of truth and the new code reads from it until cut-over. Writing the same records from both systems without a clear owner is how strangler migrations end up with drift that nobody can reconcile. Decide ownership per slice, write it down, and add a check that compares the two sides until the old path is deleted.

The pattern turns one large, all-or-nothing bet into many small, reversible ones. If a slice goes badly, you route traffic back. If priorities change halfway through, you still have a working product.

How to make the decision with evidence

Decide after a short, structured audit, not after a gut reaction to the code. An audit should answer four questions in writing: what is dangerous right now, what is slowing you down, whether the data model can carry the next stage of the product, and what each option would cost in sprints.

If you cannot point to the part of the foundation that cannot be fixed in place, you do not need a rewrite yet.

This is how our Rescue Audit works. It is fixed-price at €690 and takes 3 business days. We review the repository, the database and its policies, auth, payments, deployment and monitoring, then deliver a prioritised risk map and a recommendation — rescue, refactor or rewrite — with the reasoning written down. If you continue with us, the audit fee is credited 100% to the rescue. Rescue and refactor work then runs in fixed-scope 2-week sprints from €4,900.

We do not recommend a rewrite unless the audit proves it in writing. Not because rewrites are always wrong, but because the burden of proof should sit with the most expensive option.

How Backloo can help

Start with the free 60-second readiness check to see which areas look weakest. If you want a full, written verdict, the vibe code rescue page describes the audit and the sprints that follow, and backend systems covers the cases where the foundation really does need replacing. The code, the repository and the cloud accounts stay yours throughout. If the problems are mostly production readiness, our pre-launch checklist and Supabase RLS checklist may be all you need — or get in touch and describe what you have.

Questions

Is it cheaper to rewrite an AI-generated app from scratch?

Rarely, once the app has real users and data. A rewrite has to rebuild every existing feature, rediscover edge cases and migrate data before it delivers anything new. Rescue and targeted refactoring usually reach a safe, maintainable state sooner.

How much does a vibe code rescue cost?

It depends on how many security and reliability gaps the app has. At Backloo, the Rescue Audit is a fixed €690 over 3 business days and is credited to the rescue; the work itself runs in fixed-scope 2-week sprints from €4,900.

What is the difference between refactoring and rewriting?

Refactoring changes the internal structure of code without changing its behaviour, in small verified steps. Rewriting replaces the implementation, often including the data model, and then migrates users and data to it.

What is the strangler fig pattern?

An incremental replacement strategy described by Martin Fowler: route traffic through a seam, move one capability at a time to a new implementation, and retire the old system once nothing depends on it.

Keep reading

  • 01 — Business · 8 min read

    What a credible 99.9% SLA looks like (and why “100% uptime” is a red flag)

    A credible SLA promises 99.9% monthly availability, measured from outside, with clear exclusions, committed response times per priority and service credits when the target is missed. That allows about 43 minutes of downtime a month. A vendor promising 100% uptime or fixed bug-fix times is either not measuring or not telling you the truth.

  • 02 — Rescue · 10 min read

    Your Lovable or Bolt app works in preview but breaks in production: the causes and the fixes

    Most AI-built apps that work in preview and fail in production break for the same handful of reasons: environment variables baked in at build time, auth redirect URLs still pointing at the preview, missing database authorization, webhooks that are not idempotent, CORS, and no error monitoring. Each one has a specific, testable fix.

  • 03 — Rescue · 9 min read

    Supabase Row Level Security checklist for AI-built apps (with SQL)

    If your app talks to Supabase from the browser, Row Level Security is your access control. Enable RLS on every exposed table, write one policy per operation using auth.uid(), keep the service_role key on the server, lock down storage buckets, and test as an anonymous user and as a second account. Copy-ready SQL below.

100 — INSIGHTS

Stuck somewhere between demo and launch?

Send us the context. You get a reply within 24 hours with a plan — or an honest no.