How to Move Off Lovable Without Breaking Your App
Moving off Lovable is more than clicking Export to GitHub. That step copies your frontend and code, but auth password hashes, RLS policies, storage objects, edge functions, secrets, and cron jobs do not travel with a git push. Follow a strict order of operations — stabilise, export, clone, host, move secrets, migrate data and policies, dry-run, then cut DNS — and you keep every user with zero downtime.
By Founder Name · Last verified: 2026-06-25
What actually transfers when you leave Lovable?
Your frontend, components, and application code port cleanly through Export to GitHub. Everything that lives in the managed Supabase backend or Lovable's build environment does not: auth password hashes, RLS policies, storage buckets, edge functions, secrets, and scheduled jobs all need deliberate, separate handling. Treating the git export as a complete migration is the single biggest cause of broken cutovers.
Think of it as two layers. The code layer (React, Vite config, Tailwind, your components) is portable and shows up in your repo. The platform layer (managed credentials, database security, background work) is configuration that Lovable injects or Supabase holds — it has to be reconstructed on the target stack before your first live deploy.
Read the What Breaks on Export table below before you start. It is the difference between a one-day move and a week of production firefighting.
Related: What breaks when you export Lovable · Export Lovable code to GitHub
What breaks on export, and what ports cleanly?
Frontend, components, and code port cleanly. The parts that break are the managed-backend pieces: bcrypt password hashes are never exported, RLS policies live in Supabase not your code, storage objects must be copied bucket-by-bucket, edge functions deploy to Supabase separately, secrets are injected at build time and vanish, and any cron schedules have to be recreated on the new host.
Use this table as your migration map. The 'Ports cleanly?' column tells you what you can ignore after a git clone; every 'No' row is a task you must complete before DNS cutover.
| Asset | Ports cleanly? | Why | What you must do |
|---|---|---|---|
| Frontend / UI components | Yes | Plain React/Vite source in the repo | git clone, npm install — nothing extra |
| Application code & routing | Yes | Lives entirely in source files | Verify build runs locally |
| Supabase table data & rows | Yes (same project) | Data belongs to your Supabase project, not Lovable | Keep the project, or pg_dump to a new one |
| Auth password hashes | No | GoTrue bcrypt hashes are omitted from exports by design | Trigger a password-reset campaign before cutover |
| RLS policies | No | Stored in Postgres/Supabase, not in your code | Export with pg_policies, re-apply CREATE POLICY |
| Storage buckets & objects | No | Files live in Supabase Storage, not the repo | Copy objects + recreate bucket policies |
| Edge functions | No | Hosted on Supabase, deployed separately | supabase functions deploy each function |
| Secrets / env vars | No | Injected at build time from Lovable's store | Re-add every VITE_ and server secret on the new host |
| Scheduled / cron jobs | No | Run by pg_cron or platform schedulers, not code | Recreate schedules on the target stack |
Related: Migrate data to your own Supabase · Move secrets to edge functions
What is the correct order of operations for migrating off Lovable?
Stabilise the current build, export to GitHub, clone locally, choose a host, move secrets, migrate data and replicate RLS, mirror edge functions and cron, copy storage, dry-run deploy, then cut over DNS. The sequence matters: doing data and RLS before a dry run lets you catch a 401 on a throwaway URL instead of in front of live users.
- 1. Stabilise: confirm the Lovable preview works before you touch anything.
- 2. Export to GitHub: Project Settings to GitHub, link the repository.
- 3. Clone locally: git clone <repo-url> && cd <project> && npm install, then npm run build to prove it compiles.
- 4. Choose a host: Vercel for React/Vite SPAs, Cloudflare Pages for global edge latency, Netlify for form-heavy or simpler builds.
- 5. Move secrets: copy every VITE_ prefixed and server-side variable into the new host's environment settings.
- 6. Migrate data: keep the same Supabase project, or pg_dump and restore into your own.
- 7. Replicate RLS: export pg_policies and re-apply CREATE POLICY statements on the target database.
- 8. Mirror edge functions and cron: supabase functions deploy each function; recreate any pg_cron schedules.
- 9. Copy storage: move bucket objects and re-apply bucket access policies.
- 10. Dry-run deploy: ship to a *.vercel.app / *.pages.dev URL and smoke-test auth, reads, writes, and payments.
- 11. Cut over DNS: update CNAME/A records, verify SSL, then trigger the user password-reset campaign.
Related: Migrate Lovable to Vercel (step by step) · Run a Lovable app locally first
How do I verify the migration is actually complete?
Run a structured completeness checklist before and after cutover. Each row maps to one asset that does not port cleanly, plus a concrete verification you can perform on the throwaway deploy URL. If any row is unchecked, you are not done — that gap is where the production incident comes from. Treat the checklist as a gate, not a suggestion.
Work the checklist top to bottom on your *.vercel.app or *.pages.dev URL while the live domain still points at Lovable. Only when every row passes do you change DNS.
| # | Task | How to verify | Done when |
|---|---|---|---|
| 1 | App builds and serves | npm run build, open the dry-run URL | Home page renders, no blank screen |
| 2 | Env vars present | Check host env settings against Lovable's list | No undefined VITE_ vars in console |
| 3 | Supabase connection | Load a page that reads data | Rows return on the new URL |
| 4 | RLS parity | Sign in as two users, attempt cross-read | Each user sees only their own rows |
| 5 | Auth flow | Sign up + sign in on the dry-run URL | Session persists, no redirect loop |
| 6 | Edge functions | Call each function endpoint | Returns 200 with expected payload |
| 7 | Storage | Upload + fetch a file | Object stores and renders |
| 8 | Payments / webhooks | Run a Stripe test event | Webhook fires, order recorded |
| 9 | Cron / scheduled jobs | Confirm schedule exists on target | Next run shows in scheduler |
| 10 | DNS + SSL | Point domain, check certificate | HTTPS valid, no mixed content |
Why can't I export Supabase auth password hashes?
Supabase stores passwords as bcrypt hashes managed by the GoTrue auth server, and exports intentionally omit them for security. If you migrate to a new Supabase project, users cannot log in until they reset their passwords. The safe play is a phased password-reset campaign timed to DNS cutover, so the only user-visible event is one reset email — not a lockout.
If you keep the same Supabase project, hashes never move and no reset is needed — you only update allowed origins. The reset campaign is required only when you move to a fresh Supabase instance, which is also when you copy storage and re-create RLS.
Related: Lovable RLS and auth best practices
How do I make sure RLS policies survive the migration?
Row-Level Security policies live in Supabase, not in your Lovable code, so a git push never carries them. If you move to a new Supabase project, export every policy and re-apply it before the first live deploy. If you keep the same project, you only add the new domain to allowed origins. A missing policy is invisible until a real user reads someone else's data.
- In the Supabase SQL editor, run: SELECT * FROM pg_policies; and save the output.
- On the target database, run the corresponding CREATE POLICY statements for every table.
- Under Authentication to URL Configuration, add the new host's domain to allowed origins/redirect URLs.
- Sign in as two different users on the dry-run URL and confirm neither can read the other's rows.
What happens to environment variables and secrets when I switch hosts?
Lovable injects VITE_ prefixed and server-side variables at build time from its own secure store, so they vanish the moment you deploy elsewhere. Missing env vars are the most common reason a migrated app returns a blank page or fails its first API call. Re-add every variable on the new host before the dry-run deploy, and confirm the host does not strip the VITE_ prefix.
For Vercel: Project to Settings to Environment Variables. For Cloudflare Pages: Settings to Environment Variables. For Netlify: Site to Site Configuration to Environment Variables.
Keep server-only secrets (service-role keys, Stripe secret keys) out of any VITE_ variable — anything VITE_ prefixed is bundled into the client. Move those into edge functions or server env instead.
Where should I migrate to, and how much does leaving cost?
Pick a host by app shape: Vercel suits React/Vite SPAs and Next.js, Cloudflare Pages wins on global edge latency and request volume, Netlify fits form-heavy or simpler builds. Cursor is the destination when you want to leave AI-assisted building behind and own the code in a real IDE. The true cost of leaving is mostly engineering time, not hosting — hosting free tiers usually cover small apps.
| Destination | Best for | What you still self-manage | Guide |
|---|---|---|---|
| Vercel | React/Vite SPAs, Next.js, edge middleware | Env vars, Supabase, RLS, edge functions | /migrate/lovable-to-vercel |
| Cloudflare Pages | Global low-latency, high request volume | Workers, env vars, Supabase, RLS | /migrate/lovable-to-cloudflare |
| Netlify | Form-heavy, plugin-driven, simpler SPAs | Functions, env vars, Supabase, RLS | /migrate/lovable-to-netlify |
| Cursor (own the code) | Leaving AI-builder workflow for a real IDE | Everything — full local dev ownership | /migrate/lovable-to-cursor |
| Your own Supabase | Owning the database and auth outright | Data, hashes, RLS, storage, functions | /migrate/lovable-to-your-own-supabase |
Related: The real cost of leaving Lovable · Move Lovable to Cursor
When should I hire an engineer instead of doing this myself?
Self-migration is realistic for a simple Vite app with no payments and a handful of Supabase tables. It gets risky once you have edge functions, real-money Stripe webhooks, multi-tenant RLS, storage, or cron. A single misconfigured RLS policy in production can expose user data, and that is expensive to reverse. When the What Breaks table has many 'No' rows for you, get a second pair of hands.
Our Lovable Migration service covers the full move: code review, env-var and secret migration, RLS parity check, storage copy, edge function and cron deployment, password-reset campaign, DNS cutover, and a post-migration smoke test — fixed price, named engineer.
Book a scoping call and we will tell you, before any commitment, whether your app is a safe DIY or a job worth handing off.
Related: Lovable Migration service (fixed price) · Book a scoping call
Frequently asked questions
Does exporting to GitHub fully migrate my Lovable app?
What breaks when I export a Lovable project?
How long does migrating off Lovable take?
Do I lose my Supabase data when I move off Lovable?
Why can't I export my users' passwords?
How do I verify the migration is complete before switching DNS?
Where should I migrate my Lovable app to?
How much does it cost to leave Lovable?
What is the biggest risk of self-migrating?
Do you offer a fixed-price migration service?
Talk to a senior engineer — not a salesperson.
Book a free 30-minute audit call. We'll diagnose what's wrong and tell you exactly what it costs to fix.