A step-by-step guide to moving your AI-built app to a self-hosted environment
By The Outliers
The Situation You're Probably In
You started with Lovable because it made building feel possible. You're more product-minded than developer-trained, you had an idea worth pursuing, and Lovable got you from nothing to something real in a timeframe that felt almost unreasonable. That first version — the one that actually looked like a product — was a genuine breakthrough.
Then the costs started adding up. Hundreds of dollars a month for a few dozen changes. Some of those changes were trivial — a misaligned label, a button in the wrong place. Others were bugs that chewed through multiple iterations to fix, each attempt costing credits, none of them giving you a clear picture of what went wrong or why. You're paying a premium to feel like you're not quite in control of your own product.
And then there's the lock-in. Your database lives inside someone else's infrastructure. No direct access, no migrations you manage, no way to query your own data without going through their interface. The moment you want to do something slightly outside what the platform handles well, you hit a wall. You're not building on your own foundation.
This guide walks through exactly how to fix that — every step, including the parts that go sideways.
The result: your full codebase running independently, your own database with direct access, your app live with automatic deployments, and a development workflow that costs around $20 a month instead of $300 or more.
Before We Start: Lovable Still Has a Role
This isn't about walking away from Lovable entirely. Lovable is genuinely excellent at what it was built for — scaffolding UI and visual design fast. What would take a developer days to build, Lovable produces in an afternoon.
The problem isn't the tool. The problem is using it as your entire development platform when it was designed to be your design layer.
The workflow that actually makes sense:
Lovable — build your screens, navigation, and visual design. Use it for what it's world-class at.
Claude Code — everything else. Business logic, backend work, database operations, bug fixes, new features.
After you migrate, you can still use Lovable to prototype new screens. Just connect your own Supabase and GitHub from the start so everything stays under your control.
Think of Lovable as your design tool, not your development platform. Once that distinction clicks, the whole workflow makes sense.
What You'll Have When You're Done
Your full codebase running independently
Your own Supabase project with complete database access
Your app live on Vercel with automatic deployments on every push
A development workflow using Claude Code at $20 a month
Full ownership of everything
First: Figure Out Which Situation You're In
Situation A — You connected your own Supabase to Lovable
Your database is already yours. Skip straight to Step 3.
Situation B — You're on Lovable Cloud (the default)
Your database is locked inside their infrastructure without direct access. This is more involved but completely doable. Follow every step from the beginning.
Before You Start: Install Your Tools
Mac
bash# Install Homebrew if you don't have it
# Install Node.js
brew install node
# Install Supabase CLI
brew install supabase/tap/supabase
# Install psql
brew install postgresql
Windows
Node.js — Download the Windows installer from nodejs.org and run it.
Supabase CLI — Install via Scoop:
scoop install supabase
Or download the executable directly from the Supabase CLI releases page on GitHub.
psql — Download PostgreSQL from postgresql.org. The psql command line tool is included. During installation you can uncheck everything except Command Line Tools.
Verify everything installed:
bashnode --version
supabase --version
psql --version
All three should return version numbers without errors.
A Note on Claude
Download the Claude desktop app from claude.ai/download. A Claude Pro subscription runs $20 a month.
The desktop app has two modes you'll use throughout this process:
Claude chat — use this whenever you hit a problem. Describe what's happening, paste the error message, and Claude will walk you through a fix. Think of it as having a senior developer available the entire time.
Claude Code — built into the same app. This works directly inside your codebase, reads your files, writes code, runs commands, and resolves issues autonomously. This does the heavy lifting during the migration.
Keep it open the whole time. It will save you hours.
Step 1 — Connect Lovable to GitHub
Go to your Lovable project → Settings → GitHub and connect a repository if you haven't already. This gives you access to your code outside of Lovable and is required for everything that follows.
Once connected, clone the repo and install dependencies:
cd your-project
npm install
The npm install step downloads all project dependencies and may take a minute.
Step 2 — Create Your Own Supabase Project
Go to supabase.com, create a free account, and start a new project. Choose a region close to your users.
Once the project is ready, go to Project Settings → API and note down:
Anon/public key — a long string starting with eyJ
Project reference ID — the xxxxxx portion of your URL
You'll need all three throughout the steps ahead.
Step 3 — Set Up Environment Variables
In your project folder, create a file called .env and add your Supabase credentials:
VITE_SUPABASE_PUBLISHABLE_KEY=your-anon-key
Open src/integrations/supabase/client.ts and check what variable names your code actually uses — look for import.meta.env.VITE_ references. The names in your .env file need to match exactly or the app won't connect.
Before your first commit — do this now:
Make sure .env is listed in your .gitignore file. If you accidentally commit it even once, your database credentials live in git history permanently and can be found publicly on GitHub.
Check it's there:
bashcat .gitignore | grep .env
If nothing appears, add it:
bashecho ".env" >> .gitignore
If you've already committed .env by mistake — rotate your Supabase keys immediately at Supabase → Project Settings → API.
If you're building a commercial product, set your GitHub repo to private. Go to GitHub → your repo → Settings → scroll to Danger Zone → Change visibility → Private.
Step 4 — Test Your App Runs Locally
bashnpm run dev
Open your browser and go to localhost:8080 (or whatever port the terminal shows).
If it loads — even with errors or a loading spinner — you're on the right track.
A loading spinner that never resolves usually indicates an environment variable mismatch. Double check that the variable names in .env match exactly what's in client.ts.
If you get a "command not found" error, confirm Node.js installed correctly and run npm install again.
Step 5 — Migrate Your Database
If you were on Situation A (your own Supabase already)
Update your .env file with your existing project credentials. You're done with this step.
If you were on Situation B (Lovable Cloud)
Your migration files are saved in supabase/migrations/ in your repo. You need to apply these to your new Supabase project.
Log in and link your project:
bashsupabase login
supabase link --project-ref your-project-ref-id
Then push your migrations:
bashsupabase db push
If it works — move to the next step.
If it fails — this is common and expected. Two reasons this typically happens with Lovable Cloud projects:
Migration file naming: Lovable saves migration files with hyphens in the name (e.g. 20250619054005-a6421be6.sql) but Supabase CLI expects underscores (20250619054005_a6421be6.sql). You'll see "file name must match pattern" errors. Claude Code can rename all of these automatically.
Missing base schema: This is the bigger issue. Lovable Cloud often creates the foundational database tables directly in their infrastructure rather than through migration files. Your migrations exist but were built on top of tables that were never captured anywhere. When you apply them to a fresh Supabase project, they fail immediately because those base tables don't exist.
In this case, open Claude Code, navigate to your project folder, and say:
"My supabase db push is failing. The migrations were built on top of a base schema that doesn't exist in migration files. Please read src/integrations/supabase/types.ts and reconstruct the base schema, then fix any migration conflicts so everything can be applied to a fresh Supabase project."
Claude Code will work through this on its own — fixing naming issues, handling duplicate tables, resolving conflicts, and applying everything in the correct order.
Once migrations are applied, deploy your edge functions:
bashsupabase functions deploy
Step 6 — Connect psql and Verify Your Database
psql gives you direct access to your database and is invaluable for debugging throughout the rest of this process.
Replace YOUR_DB_PASSWORD with your database password from Supabase → Project Settings → Database.
Once connected you'll see a postgres=> prompt. Useful queries:
sql-- Confirm your tables exist
\dt
-- Check users were created
SELECT id, email FROM auth.users;
-- Check profiles were created
SELECT id, email, role FROM profiles;
-- Exit
\q
Keep a terminal tab with psql open throughout your testing. It's the fastest way to verify whether data is actually reaching your database.
Step 7 — Fix Common Silent Failures
After migration you may find things appear to work — success messages show up — but data doesn't actually save. This is almost always a Row Level Security issue.
Supabase RLS blocks all database operations by default unless you have explicit policies permitting them. When a policy is missing, writes fail without any error message — nothing saved, no indication why.
Check what policies exist on your main tables:
sqlSELECT tablename, policyname, cmd FROM pg_policies ORDER BY tablename, cmd;
Look for any user-owned tables missing INSERT or UPDATE policies. If you find gaps, tell Claude Code what you found and ask it to create a migration to add the missing policies.
Also verify that new signups are creating profile rows:
sqlSELECT id, email, role FROM profiles;
If this is empty after signing up, your auth trigger has an issue. Describe it to Claude Code and ask it to investigate and fix the profile creation trigger.
Step 8 — Deploy to Vercel
Go to vercel.com and sign up with your GitHub account. Click Add New Project and import your repository.
Before deploying, add your environment variables in the Vercel interface — the same values as your .env file.
Click Deploy.
Every push to your main branch automatically deploys to production. Every branch you create gets its own preview URL for testing before you merge. All free on the hobby plan.
Step 9 — Add Third Party Service Secrets
Your edge functions need credentials for services like Stripe, email providers, and SMS. These need to be added as Supabase secrets — not just in your .env file.
Search your supabase/functions/ folder for Deno.env.get( calls to find what services your app uses. Then add each one:
bashsupabase secrets set YOUR_SERVICE_KEY=your_value --project-ref your-project-ref
Verify what's been set:
bashsupabase secrets list --project-ref your-project-ref
Step 10 — Reconfigure Google OAuth (If You Use It)
In Google Cloud Console:
Go to your OAuth client → add your Vercel domain to Authorised JavaScript origins
In Supabase:
Go to Authentication → Providers → Google
Enable it and paste in your Client ID and Secret
Important: Search your codebase for any imports from lovable.dev/cloud-auth-js. If you find any, they need to be replaced with standard Supabase auth calls. Lovable uses its own auth library that routes through their infrastructure — if you miss this, Google login will fail with a 404. Ask Claude Code to find and replace any Lovable auth imports.
Step 11 — Test Everything End to End
Before calling the migration complete, manually test every main user flow on your Vercel URL:
Sign up as a new user
Log in and log out
Google OAuth if you use it
Any onboarding flows
Creating and saving data — verify in psql that it's actually there
Role-based flows if your app has them
Payment flows in test mode if you have Stripe
Use psql to verify data after each test. Don't rely on success messages alone — silent failures are common after a migration and psql is the only way to be certain.
Step 12 — You're Done
If you've followed every step, here's where you stand:
A fully independent production app that no platform can lock you out of. Your own Supabase database with direct access and complete control. Your app live on Vercel with automatic deployments on every push. Google OAuth, third party services, and edge functions all running. A development workflow powered by Claude Code at $20 a month.
From here, every new feature gets built in Claude Code, tested locally, pushed to a preview branch, and merged to production when you're satisfied. No credits, no limits, no waiting for a prompt to be interpreted correctly.
Your app is yours.
Using Claude Throughout This Process
Every time something doesn't work, describe it to Claude in chat. Paste the exact error message and explain what you were trying to do. Claude will help you understand what's happening and tell you what to do next.
Then use Claude Code to implement the fix. Claude Code can read your entire codebase, trace issues across multiple files, write fix migrations, and deploy changes — all without you needing to understand every line involved.
The combination of Claude for diagnosis and Claude Code for execution makes this migration manageable for anyone, not just experienced developers.
Your Ongoing Development Workflow
Once migrated, your day-to-day development process:
Describe what you want to build to Claude — get a plan and a clear prompt
Switch to Claude Code — let it build the feature
Test locally at localhost:8080
Push a branch — Vercel creates a preview URL automatically
Test on preview
Merge to main — production deploys automatically
Total monthly cost: $20 for Claude Pro. Vercel and Supabase are free at early stage.
© 2025 The Outliers. All rights reserved.
This material is the original intellectual property of The Outliers and may not be reproduced, distributed, or resold without written permission.