← all posts

How to Deploy a Vibe-Coded App to Production: The Checklist

“Production” means three things: real users, a real domain, and someone watching when things break. Most vibe-coded apps go live missing all three. Here’s the 16-item checklist I run before any app I work on goes live, in five passes, in order.

Production means three things. First: real users with real data. Second: the app is accessible at a real domain that you own. Third: when something goes wrong at 3am, somebody knows it went wrong. Most vibe-coded apps go live missing all three. The preview URL becomes the URL. The owner doesn't notice there's a difference until the app breaks.

This is the checklist I run through before any vibe-coded app I work on goes to production. Sixteen items in five passes. Two to four hours of focused work if nothing's wrong, longer if things need fixing. Do it once with attention and the app will hold. Skip it and you'll do all of it later anyway, but under pressure, with users watching.

The order matters. Security first, because that's the thing that ruins your reputation. Then data, reliability, performance, launch. Don't skip ahead.

01Preparation (3 items)

1.1: Get a summary of what the app actually does. If you didn't write the code yourself, paste it into Claude or your AI tool of choice and ask: list every page, every API endpoint, every external service this app talks to, and every database table. You need that list before you can audit anything.

1.2: Inventory every external service. Stripe, OpenAI, Resend, Twilio, anything that has an API key. Write them down. You'll come back to this list in the security pass.

1.3: Decide who owns deployment. If it's you, fine. If it's a co-founder, agree before launch, not after the first 3am incident. Someone needs to be the person who can roll back a bad deploy.

02Security pass (5 items)

2.1: Enable RLS on every user-data table. The single most common gap in vibe-coded apps. If you're on Supabase, check the table editor; anything red needs policies. The RLS guide covers exactly what to do.

2.2: Verify auth is checked on the server, not just the browser. A login screen that lives only in your React code is a UX feature, not a security boundary. Every API endpoint that returns user data must independently verify the session. Test by deleting your auth cookie and trying to call your API directly. If it returns data, your server isn't checking.

2.3: Move every API key out of front-end code. Open your deployed app, hit F12, search the network tab and the bundled JS for “Bearer”, “sk-”, and any key that looks like a token. If you find Stripe live keys, OpenAI keys, or service-role Supabase keys, they're public. Regenerate them and move them to server-side environment variables.

2.4: Sanitize error messages. Trigger a deliberate error in your app: send bad JSON, hit an endpoint with a missing parameter. Read what comes back. If the response mentions database hostnames, file paths, or stack traces, wrap your endpoints in a generic error handler that logs the real error server-side and returns a clean message to the user.

2.5: Add rate limiting on public endpoints. Especially anything that hits a paid API (OpenAI, Stripe) or sends email. Without it, one motivated user can run up a four-figure bill in an afternoon. Vercel has built-in rate limiting; Supabase Edge Functions support it; Cloudflare offers it at the DNS layer for free.

// the rate-limit horror story
Last month I audited an app that wrapped GPT-4 with no rate limit. A single user wrote a script that hit the endpoint 8,000 times overnight. The OpenAI bill was $1,200. The fix is twenty minutes of work and saves you from a category of disaster you don't want to experience.

03Data pass (3 items)

3.1: Separate development and production databases. If you have one Supabase project and it powers both your localhost work and your live app, you have a problem. Create a second project for production. Your dev and production should never share a database. Too many accidents start with “I thought I was on dev.”

3.2: Enable automated backups. Supabase Pro does this automatically. On the free tier, you need to either upgrade before launch (recommended) or set up a manual daily export. The day you wish you had a backup is not the day to start thinking about it.

3.3: Make sure your schema is reproducible. Can you spin up a fresh database from scratch with all your tables, columns, and policies? If the answer is “I clicked around in the Supabase UI and I'm not sure how to repeat it,” that's a problem. Export your schema as SQL and keep it in your repo.

04Reliability pass (3 items)

4.1: Install error tracking. Sentry's free tier handles 5,000 errors a month, which is enough for any app this side of “going viral.” Install it in your frontend and your API routes. Without this, your debugging method is “wait for users to complain,” which is the worst possible debugging method.

4.2: Set up uptime monitoring. Better Stack and UptimeRobot both offer free tiers that ping your URL every 5 minutes and email you when it's down. Five minutes of setup, peace of mind for the rest of the app's life.

4.3: Confirm your logs are accessible. Vercel keeps the last hour of function logs on the free tier, which is barely enough. If you need longer retention, pipe logs to a service like Axiom (generous free tier) or upgrade Vercel. Either way: know where your logs live, so when you need them at 11pm you don't have to figure it out then.

05Launch pass (2 items)

5.1: Point your custom domain and verify SSL. Don't ship on your-app.vercel.app or your-app.lovable.app. The trust signal of a real domain is substantial. Cloudflare handles the DNS, Vercel handles the SSL, both free. After it's pointed, load the site in an incognito window and confirm the padlock icon shows.

5.2: Run a full smoke test. The exact sequence: sign up as a new user, do the app's main action, log out, log back in, do the main action again, log in as a second user, verify the second user can't see the first user's data, trigger an intentional error, confirm error tracking caught it. If all of that works, you're production-ready.

Most vibe-coded apps go live missing all three definitions of production. The preview URL becomes the URL. The owner doesn't notice until the app breaks.

The realistic timeline

If your app has none of these in place (typical for a freshly vibe-coded project), expect 6 to 10 hours of work spread over two or three sessions. If you've already done some of it (you have auth, you have RLS), expect 2 to 4 hours. If you've never deployed anything beyond a Lovable preview URL, find someone to do the launch with you the first time. The second time is much faster.

Either way: don't launch without the security pass. Everything else can be added after (error tracking, monitoring, backups), but the security gaps grow more dangerous with every day they're live.

If you want us to run this checklist on your app and tell you exactly what's missing, the free 3-minute audit covers most of it automatically. The full audit, including the items only a human can verify, takes us 3 to 5 days.

// keep reading

Row Level Security (RLS) Explained for Non-Technical Founders

The $0 Stack for Hosting a Vibe-Coded App

Why Your Vibe-Coded App Breaks With Real Users

// don't wait until it breaks

See what's broken in your app.

3 min · no account · no spam

→ Check your app free