Your vibe-coded app works locally. Now what?
Most vibe coding tutorials end when the app runs on localhost. This guide covers the steps nobody talks about: going from 'it works on my machine' to a live URL with real users.
The gap nobody talks about
You spent two hours with Claude or Cursor. Your app looks great. The buttons work. The database stores data. You feel like a wizard.
Then you try to share it with someone, and everything falls apart.
This is the most common place vibe coders quit. Deployment is harder than building, and almost no tutorial covers it. Most vibe coding content ends with "and now you have a working app" as if the job is done.
It is not done. The job just changed.
Why localhost is a lie
Your local machine is a bubble. Inside that bubble, everything is wired together: your database file sits in the project folder, your API keys live in a .env file, and your browser talks to localhost:3000 over a direct connection.
In production, none of that exists. Here is what breaks, and why.
Environment variables disappear
Your .env file does not deploy with your app. Every hosting platform handles environment variables differently. If your app reads process.env.DATABASE_URL and that variable is not set on the server, your app crashes on the first request.
What to do: Before deploying, list every environment variable your app needs. Check every file that references process.env. Set each one in your hosting platform's dashboard.
The database is not there
If you used SQLite (a local file), your database is literally just a file on your laptop. When you deploy, that file does not exist on the server. If you used an ORM like Prisma or Drizzle, it might try to create the file but fail due to permissions.
What to do: For serious projects, switch to a hosted database. Supabase, Neon, PlanetScale, and Turso all have free tiers. For simpler projects, make sure your hosting platform supports persistent file storage (not all do).
Authentication breaks
Auth libraries like NextAuth, Better Auth, or Clerk rely on callback URLs. Locally, the callback points to http://localhost:3000/api/auth/callback. In production, it needs to point to your real domain. Miss this step and your login page redirects to nowhere.
What to do: Update your auth provider's callback URLs to include your production domain. Most auth libraries need both NEXTAUTH_URL (or equivalent) and the callback URL configured in the provider dashboard.
CORS blocks everything
Your frontend and backend talk freely on localhost because they share the same origin. In production, if your API lives on a different domain or subdomain, the browser blocks requests by default.
What to do: Configure CORS headers on your API to allow requests from your frontend domain. Most frameworks have a CORS middleware or plugin.
The deployment checklist
Before you deploy anything, run through this list. Print it out. Tape it to your monitor. Every item here has ruined someone's launch.
1. Lock your dependencies
Run npm install (or your package manager's equivalent) and commit the lock file (package-lock.json, yarn.lock, or pnpm-lock.yaml). Without a lock file, your production build might install different package versions than you tested with.
2. Test the production build locally
Run npm run build before deploying. This catches errors that the dev server ignores: missing imports, type errors, broken image paths, and pages that fail to render without client-side JavaScript.
3. Audit your environment variables
Create a .env.example file that lists every required variable with placeholder values. This serves as documentation for your future self and anyone else who needs to deploy the app.
DATABASE_URL=postgresql://user:password@host:5432/dbname
AUTH_SECRET=generate-a-random-string-here
NEXT_PUBLIC_APP_URL=https://your-domain.com
4. Check your secrets
Search your codebase for hardcoded API keys, passwords, and tokens. AI-generated code sometimes embeds credentials directly in source files instead of reading them from environment variables. This happens more often than you think.
# Search for common patterns
grep -r "sk-" ./src
grep -r "password" ./src
grep -r "secret" ./src
5. Set up error tracking
Localhost crashes show in your terminal. Production crashes vanish into the void. Use a free error tracking tool (Sentry has a generous free tier) so you know when things break.
Picking a hosting platform
The right platform depends on what you built. Here is a simple decision tree.
Static site (HTML, CSS, JS only): Use Cloudflare Pages or Vercel. Both have free tiers. Deployment takes under a minute.
Next.js, Nuxt, or SvelteKit app: Vercel (for Next.js) or Cloudflare Pages (for most others). These platforms understand these frameworks natively.
App with a server and database: Fly.io, Railway, or Render. These give you a full server with persistent storage. Expect to configure more, but you get more control.
Go app: Compile to a single binary and deploy to any Linux server. Fly.io, Railway, and Render all handle Go apps well.
noprod handles all of this for you. Your workspace is already live at a public URL the moment you create it. No deployment step, no environment variables to configure, no CORS to debug.
The first deploy
Whatever platform you choose, the flow is roughly the same:
- Push your code to a Git repository (GitHub, GitLab)
- Connect the repository to your hosting platform
- Set your environment variables in the platform dashboard
- Trigger a build and watch the logs
- If it fails, read the error message. It usually tells you exactly what is missing
The first deploy almost never works on the first try. That is normal. Read the logs. Fix the error. Try again. Most issues are missing environment variables or failed build steps.
After deployment: the things you forget
Your app is live. Users can visit it. But you are not done yet.
Set up a custom domain
A .vercel.app or .fly.dev URL works for demos, but not for anything you want people to take seriously. Buy a domain (Cloudflare Registrar, Namecheap, or Porkbun are good options) and point it at your hosting platform.
Enable HTTPS
Most modern platforms handle this automatically. If yours does not, use Let's Encrypt. There is no excuse for serving a site over plain HTTP in 2026.
Add basic analytics
You need to know if anyone is actually using your app. Plausible, Umami, or even a simple hit counter will tell you more than guessing.
Set up backups
If your app has a database, back it up. Automated daily backups cost almost nothing and save you from the worst day of your project's life.
The real lesson
Deployment is not a separate skill from building. It is the second half of building. An app that only works on your machine is a prototype, not a product.
The good news: once you deploy one app, the second time is ten times faster. Most of the knowledge is transferable across projects and platforms.
The even better news: platforms are getting simpler every month. The gap between "works locally" and "works in production" is shrinking. And tools like noprod skip the gap entirely by giving you a live environment from the start.
Start building. Ship it. Fix what breaks. That is how every real product begins.
Want to skip the deployment headache entirely? noprod gives you a live workspace with a public URL from the moment you start. No deploy step needed.