We are going to start with the folder structure
1. Setting up the directory ,Git and installing dependencies.
Start by creating a project directory with a clean structure
mkdir express-typescript-boilerplate // or any folder name you like.
cd express-typescript-boilerplate
mkdir src
mkdir src/routes src/controllers src/middlewares src/utils src/types // best practice.
Final structure (for now) will look like this :
express-typescript-boilerplate/
├── src/
│ ├── controllers/
│ ├── middlewares/
│ ├── routes/
│ ├── types/
│ ├── utils/
│ └── index.ts
├── .env
├── .gitignore
├── package.json
├── tsconfig.json
└── README.md
Initialize Git and NPM
git init
npm init -y
Install the dependencies
npm install express dotenv
npm install --save-dev typescript ts-node-dev @types/express @types/node
What we have done here :
express
– web frameworkdotenv
– env configtypescript
– TypeScript compilerts-node-dev
– Dev server with hot-reloading@types/express
and@types/node
– required type definitions
2. Configuring TypeScript
Run the following command. It create a tsconfig.json
file. This file contains settings for compiling the TS code into plain JavaScript.
npx tsc --init
Then Modify the tsconfig.json
{
"compilerOptions": {
"target": "ES2020",
"module": "commonjs",
"rootDir": "./src",
"outDir": "./dist",
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true
}
}
Explaination :
target: "ES2020"
: Transpile TypeScript to ES2020 JavaScript (supports features like optional chaining, nullish coalescing).module: "commonjs"
: Use the CommonJS module system (for Node.js compatibility).rootDir: "./src"
: Specifies the source code directory as./src
. Picks files from here to be compiled.outDir: "./dist"
: Outputs compiled JavaScript files to./dist
directory.strict: true
: Enables strict type-checking options (e.g.,noImplicitAny
,strictNullChecks
).esModuleInterop: true
: Allows ES6import
syntax with CommonJS modules. example :import * as fs from 'fs'
becomesconst fs = require('fs');
skipLibCheck: true
: Skips type-checking of third-party.d.ts
declaration files for faster builds.
NOTE : Since our tsconfig.json is configured to create a commonjs module project, you have to make sure your project doesn't have dependencies that are purely ESM.
Otherwise you will have to make the project "module" and change the tsconfig configuration. Also you will then need to add .js to all the relative imports (even if the file is actually .ts)
Setup .gitignore and .env
// .gitignore
node_modules/
.env
// .env
PORT=8080
Write the index.ts
Now we will write a basic index.ts (or app.ts or whatever you wanna call it) to serve requests to endpoints.
import express from 'express';
import dotenv from 'dotenv';
// Config ENV
dotenv.config();
const app = express();
const PORT = process.env.PORT || 8080;
// Middlewares
app.use(express.json()); // to read the request body
// Routes
app.get('/', (req, res) => {
res.send('Hello World!');
});
// Start Server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Running the Server in Dev mode
Add the following scripts to the package.json
"scripts": {
"dev": "ts-node-dev --respawn --transpile-only src/index.ts",
"build": "tsc",
"start": "node dist/index.js"
}
Note that the start script will start the index.js
from /dist
.
To run the server, just type
npm run dev
And your server will be running.
Building the code
To build the JS code from our Typescript files, all you need to do is
npm run build
This will create a /dist
directory with all our transpiled code.
Setup for Vercel (vercel.json)
Before deploying to Vercel , we need to tell vercel about our entry point i.e thd dist/index.js
.
We do this by creating a vercel.json
file in our root directory.
// vercel.json
{
"version": 2,
"builds": [
{ "src": "dist/index.js", "use": "@vercel/node" }
],
"routes": [
{ "src": "/(.*)", "dest": "dist/index.js" }
]
}
Pushing to Github
Finally, it is the time for pushing our entire code to github. This will be the source for our vercel deployment.
Note : Any changes committed to the "main" branch of github repo will trigger an auto deploy in vercel to reflect new changes in the application
git add .
git commit -m "Initial commit"
git branch -M main // to switch the branch
git remote add origin <your-repo-url> // you'll get this from your github dashboard when you create a "New Repo"
git push -u origin main
Deployment to vercel
Go to Vercel Dashboard (create an account if you don't have one)
Click “New Project”
Import your GitHub Repo (choose the one you just created)
Configuration :
Framework Preset: Other
Build Command:
npm run build
Output Directory: leave blank (as we are already redirecting requests to
dist/index.js
Add your
.env
variables in Vercel Dashboard (Environment Variables section)
Hit the Deploy button
Your Express + TypeScript Backend is Live!
Vercel will give you a domain via which the web server will be accessible. You can change it according to you in the Domains tab
If you encounter build errors, you can see the "logs" tab for identifying and resolving errors
Bonus Tips:
Add CORS middleware if your frontend is on another domain (most probably)
For production-grade APIs, integrate a logging system (like Winston or Pino)
Add vercel analytics to your applications code for monitoring, guide can be found here
Add a Readme.md to explain your project