vite-plugin-to-express
Vite Plugin API → Express Production Server
Trigger
- App has API routes embedded in a Vite plugin (e.g.,
vite-plugin-api.ts)
- Need to deploy to production where Vite dev server won't run
- API uses
server.middlewares.use() or custom route handlers inside Vite plugin
Steps
- Identify the Vite plugin API file — usually registers routes via
configureServer hook
- Create
server.js (or server.ts) standalone Express app:
- Copy all route handlers from the Vite plugin
- Replace Vite middleware patterns with Express app.get/post/put/delete
- Add express.static('dist') to serve the built frontend
- Add catch-all route for SPA: app.get('/{*splat}', ...) (Express 5) or app.get('*', ...) (Express 4)
- Build frontend:
npm run build → produces dist/
- Database connection: Keep the same pg Pool config, just update host/port for production
- Run with PM2:
pm2 start server.js --name app-name
Pitfalls
- Express 5 catch-all syntax: Use
/{*splat} NOT * — Express 5 rejects bare * wildcards
- tsx caching: When using
tsx to run TypeScript, kill the process fully and restart after file changes — tsx can cache old versions
- Port conflicts: Check if Postgres 5432 is already in use; use alternate port (e.g., 5433) for Docker Postgres
- Static file path: Use
path.join(__dirname, 'dist') or resolve relative to server.js location
Verification
curl http://localhost:PORT/api/health # API responds
curl http://localhost:PORT/ # Frontend HTML served