How to Deploy TypeScript Express App to Vercel
Recently, I’ve been refactoring a project, and after updating it, Vercel deployment completely broke. The backend kept throwing 404 or 500 errors and just wouldn’t work properly. After a long debugging session and trying countless fixes, I finally got it running again. I’m documenting the solution here for future reference.
This project follows a frontend-backend separation approach:
- Frontend: React
- Backend: Express
- Language: TypeScript
- Deployment: Vercel
Vercel’s Serverless Function only run when triggered by a request. That means all API endpoints must be routed through
api/index.ts, which serves as the entry point for the Express app. Additionally, request forwarding must be configured invercel.jsonto ensure proper routing.
Backend Folder Structure:
Setting Up the Express Server:
To check if the backend is running properly, I added a simple homepage route that returns a response.
import express from "express";import cors from "cors";
const app: express();
app.use(cors());app.use(express.json());
// confirm the backend is workingapp.get('/', (req, res) => res.send('Express on Vercel.'));
export default app;Entry Point for Vercel:
Vercel only executes files inside the api/ folder as API endpoints, we need to create index.ts in api folder to load our Express app.
import app from '../src/app';
export default app;If your Express app isn’t located inside api/, you’ll need to configure a rewrite rule to redirect.
Routing Requests Correctly:
This config file ensures that all incoming requests are routed to api/index.ts.
{ "version": 2, "builds": [ { "src": "api/index.ts", "use": "@vercel/node" } ], "routes": [ { "src": "/(.*)", "dest": "/api/index.ts" } ]}No special configurations are needed in tsconfig.json or package.json.
Deployment Success!
Once deployed, visiting the backend URL should display “Express on Vercel.” (the response from the homepage route)
If you see this, congratulations—your backend is up and running! 🎉