The Vibe Coder's Pre-Launch Checklist: 20 Things to Check Before You Show Anyone

The AI built the thing in an afternoon. That part feels like magic.
Then you try to actually SHIP it, and you find out building was the easy 10%. The other 90% is everything the AI quietly skipped: the part where a real human clicks a button you didn't expect, the part where your API key is sitting in plain text, the part where it works perfectly on your laptop and dies the second it touches a real server.
I build and sell a CRM that I largely vibe-coded my way through. I've shipped broken code to people who paid me. I've watched a deploy work on my machine and crash on the host every single time. So this isn't me lecturing from a mountaintop. This is the checklist I now run on everything before I let another human near it, written from the scars.
Twenty things. Five buckets. Run it top to bottom before you show ANYONE.
Bucket 1: Don't get pwned (the security pass)
This is the one that actually ends startups. A founder bragged that 100% of his app was written by AI, zero hand-written code. Days after launch, people figured out anyone could unlock the paid features and edit other users' data. The AI wrote code that runs. It does not write code that's safe, because it has no concept of someone actively trying to break in.
1. Grep your entire codebase for secrets. API keys, database passwords, Stripe keys, anything. The AI LOVES to paste a key inline "just to get it working." Every secret belongs in an environment variable, never in a file you commit. On Seedly, my Stripe secret key lives only in the host's env config. The day it went missing from the server, every single checkout threw an error, but at least it was never sitting in my code for someone to find.
2. Lock down who can read and write what. For every page and every API route, ask one question: what happens if a logged-OUT person hits this? Or a different logged-in user pokes at someone else's data? "It's not linked in the menu" is not security. If the URL works, assume a stranger will find it.
3. Verify every package the AI imported actually exists. This is a real attack now. AI sometimes invents a package name that sounds right but doesn't exist, attackers register that exact name with malware inside, and your "npm install" pulls it down. Read your dependency list. Google anything you don't recognize.
4. Validate every input. Every form field, every URL parameter, every API body. The AI assumes everyone sends clean, polite data. Real users paste emoji into number fields and real attackers paste in things designed to break your database. Reject what you didn't ask for.
Own your CRM. No subscriptions. Ever.
One payment. Full source code. Unlimited seats. Deploy anywhere, customize everything.
See what's includedBucket 2: Does it survive a real human (the unhappy path)
AI optimizes for the "happy path," the version where everything goes right. Production is nothing but unhappy paths. Slow networks, empty states, double-clicks, expired logins, the back button.
5. Use the app while logged out, on purpose. Here's one that cost me. My download page subtracted one from a user's "downloads remaining" count BEFORE it actually checked whether the file existed. So during pre-launch, when the file wasn't uploaded yet, every click burned a download slot AND sent the user to a 404. Worked great in testing because I always had the file. Broke for the exact person it mattered for.
6. Test every empty and "first time" state. Brand new account with zero data. A list with nothing in it. A search that finds nothing. The AI builds the screen that's full of data because that's what it imagined. The empty version is where it falls apart.
7. Make every action handle failure out loud. What does the user see when the save fails? When the payment is declined? When the network drops mid-click? If the answer is "a spinner that spins forever," you have a bug. Every action needs a visible success AND a visible failure.
8. Open it on your phone. Just do it. Half of vibe-coded apps look perfect at 1440px wide and become an unusable mess the second they hit an actual phone, which is where most people will actually open your link.
Bucket 3: Can you ship it AND un-ship it (deploy and recovery)
Building is instant now. Deploying is somehow still stuck in 2015. This bucket is where most people rage-quit at 1am.
9. Put it in version control before you do anything else. Git. From the start. The single most reported vibe-coding nightmare is "the AI fixed one thing and broke ten others." Your only defense is being able to roll back to the version that worked five minutes ago. No git, no undo, and you WILL need the undo.
10. Make sure your database matches your code before you push. I've been burned by this more than anything else. If your code expects a new database field that isn't actually there in production yet, your app doesn't show an error, it just dies. Stale schema equals instant 500. Sync the database FIRST, then push the code. Never the other way around.
11. Deploy all the pieces, not just the pretty one. A lot of these tools deploy your frontend beautifully and silently leave your backend behind. On one of my projects, my CI was only deploying the website and not the backend functions. The site loaded fine, then exploded the moment anyone clicked anything, with a "function not found" error I chased for an hour. If your app has a backend, confirm with your own eyes that the NEW version of it is live.
12. Confirm it actually boots in production, not just on your laptop. My host marked every single deployment as CRASHED for a while. The app ran perfectly locally. Turned out production needed a health check endpoint and a clean shutdown handler that I'd never needed on my machine. "Works on my laptop" and "works on the server" are two completely different claims. Verify the second one.
Bucket 4: Will you even know when it breaks (monitoring)
If a user hits an error and you don't find out, you don't have an app, you have a slowly-leaking bucket.
13. Add error logging and a way to see it. When something throws at 2am, you need a place where that error gets recorded. Flying blind means you only learn about bugs when an angry user emails you, if they bother emailing at all.
14. Confirm your notification emails actually arrive. This one still makes me wince. A client's contact form was generating leads like clockwork, then one day, nothing. No error. The form submitted fine. Turns out an email update silently rerouted the notification emails into the void. By the time we caught it, 50 real people had asked for help and heard nothing back. If your app emails you or your users, send a real one and confirm it lands in an inbox, not spam, not nowhere. A bad sender setup quietly eats everything, and you can check your email deliverability here before it bites you.
15. Put a timeout on anything that calls another service. Payment providers, AI APIs, email services. If you call out to something and it hangs, your whole app can hang with it. I've had background jobs sit frozen for DAYS because one call had no timeout and nothing to kill it. Every external call needs a "give up after X seconds" rule.
16. Cap your spending before it caps you. People burn through twenty bucks of AI credits in a single confused session asking the bot to fix the same bug. Same thing happens with hosting and API bills once real traffic shows up. Set a budget alert. Know what your app costs to run per day BEFORE a stranger on the internet decides to hammer it.
Bucket 5: The stuff that bites the week after launch
You shipped it. You're not done. This is where the "almost working" app slowly turns into a real one, or quietly falls apart.
17. Never trust "I fixed it." Re-test the actual thing. The AI will tell you, with total confidence, that the bug is gone. It is frequently lying, not on purpose, it just can't run your app. Click the exact thing that was broken, yourself, every time. "The agent says it's fixed" is not a test.
18. Treat changing a field as a multi-step job, not one prompt. Want to remove or rename something in your database? In a live app, that's never a single move. You stop using it in the code first, THEN clean up the data, THEN remove it from the structure. Do it in one shot and you'll freeze production. I treat every schema change as a three-step process now, because the one time I rushed it, I took the whole thing down.
19. Run your checks before every release, and NEVER skip them to save time. My most embarrassing one. I had a build step that verifies the code before it ships. One release, I ran it with the "skip verification" flag to move faster. The build quietly left out a handful of required files. My paying customers downloaded it, tried to set it up, and got a flat-out error on first run. I'd shipped a broken product to people who trusted me with money, specifically because I turned off the seatbelt to save ninety seconds. The check exists for the exact moment you're tempted to skip it.
20. Keep a one-page spec and a running log of decisions. The single biggest difference between a vibe-coded mess and a vibe-coded app that holds together is context. Write down, in plain language: what the app does, who it's for, the main screens, and the key decisions you made and why. Feed it back to the AI at the start of every session. Most "the AI keeps breaking my code" pain is really "the AI forgot what we were building," and that's on you to fix, because it can't remember for you.
The actual point
None of this is about being a "real programmer." You don't need to be. Vibe coding genuinely works, I've built a product I sell with it.
But the gap between "it runs on my screen" and "a stranger can use it without it leaking, crashing, or ghosting them" is real, and the AI will not close that gap for you. It builds the demo. You ship the product. This list is the difference.
If you want the deeper version of why I stopped renting my software and started owning the code outright, I wrote up the real numbers from self-hosting. And if you're weighing building your own thing from scratch versus starting from something that already passed this checklist, here's why I'd fork instead of build.
Run the twenty. Then show somebody.
Own your CRM. No subscriptions. Ever.
One payment. Full source code. Unlimited seats. Deploy anywhere.

