Services like Vercel and Render is pretty damn good for deploying your web-app especially if you have a low usage or for prototyping, and I recently had to get this done, so might as well document it here.
First, let's start with the express.js backend.
Starting with the express.js backend
Let's say you have a GitHub repo with backend/ folder having a npm package with your express app,
where the server.js is the main file to handle that, which should look like this:
import express from 'express'
const app = express()
//all your middlewares, routes, controllers, etc...
export default app
Instead of defining the port, just export the express app object, vercel handles running that.
Then define a vercel.json file to pinpoint the config that the server.js file is the main source (same dir as package.json in backend/):
{
"version": 2,
"builds": [
{
"src": "server.js",
"use": "@vercel/node"
}
],
"routes": [
{
"src": "/(.*)",
"dest": "server.js"
}
]
}
Although vercel by default looks for index(.ts/.js) or server(.ts/.js), its better to be explicit about it.
That's all the config you need, now just create a new project in your vercel account (connect with GitHub first):
There's three main config:
- framework preset: choose express
- build & output: leave default
-
env: pass your
.envfile details, that can be access in app asprocess.env.<ENV>
And then test your application works!
React.js frontend deployment
There's relatively little config needed for react, I'm using vite here, but it's the for create react app
Back on the vercel new project:
Use the framework preset as react app/vite, it will handle the build output by itself (vite build or react build accordingly)
Now for env, it's usually best practice to have the API endpoint address to backend in a env, so let's assume you have API_URL as the API path to backend.
From the express deployment earlier, get the address:

And then pass inside "Environment Variables" the API_URL while making the frontend deployment.
Now test your apps and see if they both work well.. (mention below if they don't)
Some good practices to just have for this:
- use CORS(cross origin) blocking in your express server (in deployment mode), and whitelist apps that need access like your react app, so user can't direct make API calls. Maybe have a "MODE" env value for this logic handling.
- like mentioned, decouple variables like configs, addresses, ports, etc into envs and pass em' later
- use typescript instead, will save you a lot of headache on issue you'll see in prod but not in dev, better to get way more possible errors than way less.


Top comments (0)