Your App Works On Your Laptop. Why Does It Crash In Production?

It works on localhost but crashes in production. Here's why your AI-generated app behaves differently when real users touch it—and how to fix it.

You tested your app. Everything works perfectly. Login works. Features work. You deploy to production.

Five minutes later: "The app is broken. Nothing loads."

But it works on your laptop!

Here's why production is different—and how to fix the 7 most common localhost vs production bugs.

Bug #1: Hardcoded localhost URLs

🔴 The Problem

Your API calls point to http://localhost:3000. On your laptop, this works. In production, it tries to connect to the server's own localhost—not your API.

// ❌ Hardcoded localhost fetch('http://localhost:3000/api/users')

✅ The Fix: Use Environment Variables

// In .env.local (development) NEXT_PUBLIC_API_URL=http://localhost:3000 // In .env.production NEXT_PUBLIC_API_URL=https://api.yourdomain.com // In your code fetch(`${process.env.NEXT_PUBLIC_API_URL}/api/users`)

Now your app uses the right URL for each environment.

Bug #2: Missing Environment Variables

You set DATABASE_URL in your local .env file. But you forgot to set it on Vercel/Railway/Render.

🔴 What Happens

Your app tries to connect to the database. DATABASE_URL is undefined. Connection fails. App crashes.

✅ The Fix: Set Environment Variables in Your Host

Vercel: Settings → Environment Variables → Add all your .env variables

Railway: Variables tab → Add each one

Render: Environment → Add environment variables

Important: Never commit .env files to GitHub. Add .env* to .gitignore.

Bug #3: CORS Errors

Your frontend is at yourdomain.com. Your API is at api.yourdomain.com. The browser blocks requests.

🔴 The Error

Access to fetch at 'https://api.yourdomain.com' from origin 'https://yourdomain.com' has been blocked by CORS policy

✅ The Fix: Enable CORS on Your Backend

// Express.js const cors = require('cors'); app.use(cors({ origin: ['https://yourdomain.com'], credentials: true })); // FastAPI (Python) from fastapi.middleware.cors import CORSMiddleware app.add_middleware( CORSMiddleware, allow_origins=["https://yourdomain.com"], allow_credentials=True, )

Bug #4: HTTP Instead of HTTPS

Your production site uses HTTPS. But your API calls use HTTP. Modern browsers block mixed content.

🔴 Browser Error

"Mixed Content: The page was loaded over HTTPS, but requested an insecure resource. This request has been blocked."

✅ The Fix

Make sure ALL your URLs use HTTPS in production:

  • API endpoints: https://api.yourdomain.com
  • Images: https://cdn.yourdomain.com
  • External resources: Always use HTTPS

Bug #5: Database Connection Limits

On localhost, you're the only user. In production, 100 users are hitting your app at once. Your database has a connection limit of 10. Queries start failing.

🔴 The Error

Error: too many connections for database

✅ The Fix: Use Connection Pooling

// Instead of creating a new connection per request const pool = new Pool({ connectionString: process.env.DATABASE_URL, max: 20, // Maximum 20 connections idleTimeoutMillis: 30000, }); // Reuse connections from the pool const client = await pool.connect(); const result = await client.query('SELECT * FROM users'); client.release(); // Return connection to pool

Bug #6: File Paths That Work Locally But Fail in Production

🔴 The Problem

// ❌ Absolute path that only exists on your laptop const file = fs.readFileSync('/Users/you/project/data.json')

In production, /Users/you/project/ doesn't exist.

✅ The Fix: Use Relative Paths

// ✅ Relative to the current file const path = require('path'); const file = fs.readFileSync(path.join(__dirname, 'data.json'))

Bug #7: Missing Dependencies

You installed a package locally but forgot to add it to package.json.

🔴 What Happens

Works on your laptop (package is in node_modules). Crashes in production (package not installed).

Error: Cannot find module 'some-package'

✅ The Fix

Always install with --save or just use npm install (it saves by default now):

npm install package-name # NOT this (doesn't save to package.json): npm install -g package-name

Before deploying: Delete node_modules and run npm install to make sure everything installs correctly.

Find Production Issues Before Launch

VibeCheck tests your app in a production-like environment and catches localhost vs production bugs before your users do.

Test My App Free →

Pre-Launch Checklist

Before you deploy to production:

  1. Check for hardcoded URLs: Search your code for localhost, 127.0.0.1, :3000
  2. Set environment variables: Copy all variables from .env to your hosting platform
  3. Enable CORS: Add your production domain to allowed origins
  4. Use HTTPS everywhere: All URLs should start with https://
  5. Test with production database: Don't use your local database for testing production
  6. Check file paths: Use relative paths, not absolute
  7. Verify dependencies: Run npm ci to ensure clean install

Quick Debug Tips

When something breaks in production but not locally:

  • Check browser console: Look for CORS, HTTPS, and network errors
  • Check server logs: Environment variable issues show up here
  • Compare environments: What's different between localhost and production?
  • Use staging: Deploy to a staging environment first to catch issues

The Bottom Line

Localhost is forgiving. Production is not.

The differences are predictable: URLs, environment variables, CORS, HTTPS, connection limits, file paths, and dependencies.

Fix these before launch, and your production deployment will be smooth.

Your app will work for users the same way it works for you.