Why Vite dev server needs a proxy (and production doesn't)

In development, your frontend runs on localhost:5173 and your API server on localhost:3000. The browser blocks cross-origin requests — that's CORS. Vite's dev proxy solves this by forwarding /api/* requests to the backend, making them look same-origin to the browser:

// vite.config.ts
server: {
  proxy: {
    '/api': 'http://localhost:3000'
  }
}

In production this proxy disappears. The built frontend is just static files (HTML/JS/CSS) — no port, no process. Nginx or a CDN serves them, and reverse-proxies /api/* to the backend the same way Vite did in dev:

user → Nginx :80
         ├── /api/*  → backend :3000
         └── /*      → dist/ static files

One port from the user's perspective, no CORS issue. The backend port is always real and needed; the frontend "port" only exists during development because Vite's dev server is a live process.

Comments

  1. Markdown is allowed. HTML tags allowed: <strong>, <em>, <blockquote>, <code>, <pre>, <a>.