When (and why) to graduate from an AI builder

Five signals it is time to leave Lovable, Replit, Bolt, v0, Emergent or Base44. What migrating actually involves, and what graduating does not fix.

7 min read·Updated May 27, 2026

An AI builder — Lovable, Replit, Bolt, v0, Emergent, Base44 — is a productive place to start. Many products live their whole lifespan inside one. Internal tools, niche SaaS, side projects that quietly make a few thousand a month. There is no rule that says "real code on your own infrastructure" is a moral upgrade.

There is, however, a moment when the builder starts costing more than it gives. This guide is about how to spot that moment, and what migrating actually involves — not a builder-by-builder walkthrough. Each platform has its own page linked at the bottom.

Five signals it is time

Hitting one is normal. Two is a conversation. Three or more is usually the answer.

1. The cost cliff. You are paying $200 or more per month, you are credit-limited by the third week, and the usage page is your most-visited tab. A Vercel hobby plan, a Supabase free tier and a Cursor seat typically cover what you are paying for, at roughly a quarter of the price.

2. The customization wall. You keep wanting one thing the tool does not natively support — a specific Stripe webhook flow, a cron job every six minutes, a custom auth provider, a library not in the sandbox. The clearest tell is when you find yourself writing prompts like "can you fake X by doing Y." That means the abstraction is fighting you.

3. Performance. Page loads are fine on a laptop and rough on a real phone. A table starts lagging past 50k rows. Image-heavy pages ship 4MB of unoptimized assets and you cannot get under the hood. Builders optimize for the average app; edge cases hit a wall you cannot tune past.

4. Lock-in risk. The product makes real revenue and depends on a single vendor's continued health. Builders are competent companies, but they are also startups. A single outage or pricing change can take a paying product offline.

5. A second person joined. Branches, code review, conflict resolution and separate dev environments are things normal codebases solve and most browser builders do not. If a collaborator is sitting on their hands waiting for the previous session to end, the tool is taxing the team.

If none of these apply, staying is the right answer. Migration costs real time, and things that worked under the builder will stop working for a day or two during the cutover.

What "graduating" actually moves

Conceptually, the move is small. The product does not change. The place it lives changes.

Most graduates land on a variation of the same stack:

  • Editor: Cursor or Claude Code
  • Frontend host: Vercel (Next.js / Vite) or Railway
  • Database, auth, storage: Supabase, or Postgres on Railway / Neon
  • Framework: the same React (often Vite or Next.js) the builder was already generating

The frontend code is usually the easiest part. What needs replacing is everything the builder bundled invisibly: CI/CD, SSL, the database, the auth system, secrets management, the AI provider accounts, the file storage. Lovable's own external-hosting documentation lists this inventory explicitly — managed authentication, row-level security, file storage, preview environments, OAuth configuration, compliance infrastructure (source). Exporting code is not the migration. Replacing platform glue is the migration.

The shape of every migration

Specific builders differ on export mechanics and what is portable. The phases are the same:

  1. Freeze. Stop making AI-builder changes. Sync or export the project to GitHub. Tag the commit (git tag pre-migration). This is the baseline to revert to if the migration goes sideways.
  2. Run locally. npm install && npm run dev. If the project does not build on a laptop, it will not build on a host either. Fix this before going further.
  3. Inventory the stack. Open package.json, check for next, vite, express, @supabase/supabase-js, prisma, drizzle. Note whether there is a supabase/ folder, a Dockerfile, a Python requirements.txt, or a .replit file. The stack determines the host.
  4. Move secrets. This is the step that quietly breaks most migrations — see the principles below.
  5. Migrate the database. If the builder used Postgres, pg_dump from the old database, pg_restore into the new. Supabase's migration documentation has working commands for this (source). If the builder used a proprietary database or NoSQL store, expect rewriting the data layer, not just moving rows.
  6. Re-wire auth, storage, webhooks. OAuth callback URLs, Supabase auth redirects, Stripe webhook endpoints, email senders. This is the step that breaks most migrations. The new domain needs to be added everywhere the old domain was registered.
  7. Deploy, switch DNS, monitor. Run the new deployment alongside the builder for a day. Once smoke tests pass, point the custom domain at the new host.

Moving your secrets safely

Every builder stores environment variables somewhere — Lovable in the Cloud tab, Replit in the Secrets tab, Base44 through its CLI, Emergent in its dashboard. The per-builder guides cover the exact UI paths. A few principles apply to all of them:

  • Enumerate before you copy. Builders rarely give you an export button. Open the secrets UI, list every key, and write them down. A missing STRIPE_WEBHOOK_SECRET does not error at build; it errors at the first payment.
  • Know which ones are public. Anything prefixed VITE_, NEXT_PUBLIC_ or REACT_APP_ is embedded into the client bundle at build time and shipped to every browser. Putting a Stripe secret key, a Supabase service-role key, or any API token there leaks it. Public-safe values: anon/publishable keys, public URLs, feature flags. Server-only values: everything else.
  • Build-time vs runtime matters. Vite reads env vars at build time. Vercel and Railway apply env changes only to new deployments — change a variable, redeploy, or the new value never takes effect.
  • Rotate, don't migrate, anything that has leaked. If a secret has been in a Slack message, a screenshot, an AI builder's logs, or a laptop you no longer use, generate a new one in the source service (Stripe, OpenAI, Supabase) and add the new value to the new host. Don't carry old secrets across.
  • Build a .env.example. Check it into the repo with empty values as a reference for what variables the app needs. Real values stay in the host's dashboard, never in git.

Two reference stacks

Vercel + Supabase. The cleanest path for a frontend-heavy app — Next.js or Vite, no long-running backend process, Supabase doing auth and Postgres. Vercel handles the frontend, builds on every push to GitHub, and ships preview URLs per branch. Fits projects coming from Lovable, v0 and most Bolt builds.

Railway + Postgres. The cleanest path for a full-stack app with a server process — Express, FastAPI, Django, queues, cron jobs, websockets. Railway has a dedicated Replit migration guide that covers code export, environment variables and Postgres migration (source). Fits most Replit projects and any Emergent build that needs its FastAPI backend running continuously.

Both stacks can be mixed: frontend on Vercel, backend services and workers on Railway, database on Supabase or Railway Postgres. There is no single right answer — pick the simpler one for the shape of the app.

What graduating does not fix

A few things people expect from migration that the move alone does not deliver:

  • It does not make the app faster by default. A slow Lovable app will be a slow self-hosted app until the actual bottleneck is addressed.
  • It does not improve security unless the work is done. Builders ship sensible defaults. A self-hosted app with a missing RLS policy or an exposed service-role key is less safe than the builder original.
  • It does not free up time. Owning the stack means owning the operations — uptime, dependency updates, SSL renewals, database backups. Most teams find the time cost is roughly the same; what shifts is where the time goes.

Per-builder migration guides

Each builder has its own export mechanics, its own bundled services, and its own gotchas:

  • Migrate from Lovable — Vite + React + Supabase. The most portable of the four.
  • Migrate from Replit — full-stack apps, often Node or Python. Railway has the official path.
  • Migrate from Emergent — FastAPI + React + MongoDB. Backend needs a long-running host.
  • Migrate from Base44 — Vite + React, but the exported code still calls Base44 backend services. Plan for partial migration first.

Next up

If the decision is to graduate, the next guide in this pillar — "Your first real deploy: Supabase + Vercel from scratch" — walks through the actual deploy end to end, from empty project to a working URL on a domain you own.

Get the next guide when it lands

One email on Sunday with new /learn guides, tool updates, and a couple of links worth reading.