VibeOps Blog
Shipping a vibe-coded app to production: the 20-minute checklist
Vibe coding solved the blank page. It did not solve deployment. The pattern is now familiar: three hours of prompting produces something that runs on localhost:3000, and then two days go by and it's still only running on localhost:3000.
The gap isn't skill. It's that the deploy is a dozen small decisions with no code to autocomplete. Here's the ordered version.
1. Find out what you actually built
Open the repo and count the services, not the folders. A service is anything that needs its own process or its own hosting: the web app, an API, a background worker, a database, a cron job.
Generated projects hide services in plain sight. A prisma/schema.prisma means you need a Postgres somewhere. A worker.ts with a queue import means a second runtime. An /api folder may or may not be part of the web deploy depending on the framework.
Everything else on this list depends on getting this count right.
2. Pick a target per service
Not one target for the project — one per service. Rough defaults that are hard to regret:
- Next.js / SvelteKit / Nuxt frontend → Vercel or Cloudflare Pages.
- Standalone API → a container host, or Cloudflare Workers if it's edge-compatible.
- Postgres → Neon or Supabase. Both have a free tier that survives a hobby project.
- Background worker → the same container host as the API, separate process.
- Cron → your host's scheduler before you reach for a queue.
Mixing hosts is fine and usually cheaper than forcing everything onto one platform.
3. Deploy in dependency order
Database first, then anything that needs its connection string, then anything that needs that service's URL. Deploying the frontend first is the most common mistake — it builds, it goes live, and every API call 500s because the thing it calls doesn't exist yet.
Write the order down before you start. Three services have six possible orders and only one or two of them work.
4. Get the environment variables right
This is where most of the two days go. The rules:
- Every
process.env.Xin the codebase needs a value in the host's dashboard. Grep for it; don't trust.env.exampleto be complete. - Local values are not production values.
localhost:5432in a deployed API is the classic 3am bug. - Client-exposed prefixes (
NEXT_PUBLIC_,VITE_) are public. Anything under one of those prefixes will be in the JavaScript bundle. Never put a secret behind one. - Set them before the first build. Most platforms bake build-time vars into the artifact, so adding one after means a redeploy.
5. Check what the AI put in the repo
Generated code has a few reliable tells worth a two-minute scan:
- A committed
.env. Checkgit log --all -- .env— if it was ever committed, the values are in history even after you delete the file. Rotate them. - Hardcoded keys in the source, usually in a "config" file, usually with a comment saying to replace them.
- CORS set to
*because that made the local error go away. - A database with no auth because the local one didn't need it.
None of these are hypothetical. All four show up regularly in repos that were generated fast.
6. Point a domain at it and verify from outside
Add the domain on the host, add the DNS record, wait for the certificate. Then check it from a device that isn't yours — a phone on cellular data, not your laptop, whose DNS cache and logged-in session will happily hide a broken deploy from you.
Load the page, hit one API route, do one write. If all three work from outside your network, you've shipped.
Doing it with an agent instead
Every step above is reading, inference, and sequencing — which is exactly what an AI agent is good at, and exactly what people don't yet use them for. The reason is usually trust: handing a token to a chatbot so it can deploy to prod is a bad trade.
That's the problem VibeOps is built around. It scans the repo and does step 1 for you, proposes a target per service, sequences the deploy in dependency order, and asks before every write. Your credentials stay in the OS keychain and get substituted into the command at execution time — the model plans the deploy without ever seeing the token.
An afternoon of building deserves better than two days of deploying.