logo
post cover

How to setup Express JS with TypeScript 2023 (Intermediate)

If you would like to build an API or the backend to your latest project using the Express JS framework and TypeScript, you've come to the right place. In this tutorial, I'll show you just how to get started in a few short steps.

  1. Create a project folder and initialise package.json
  2. Install project dependencies
  3. Initialise TypeScript
  4. Create an Express JS app
  5. Create scripts for production and development
  6. Quality of Life changes & folder structure suggestion

Create a project folder and initialise package.json

Each Node project's package.json file is its beating heart. It establishes the functional properties of a project that npm makes use of to set up scripts, install dependencies, and locate the entry point for our package. If you want to know more about this file, you will find the information here. We will be using it to install the dependencies and types needed for our project.

Open up your terminal, navigate to the desired directory, and run the following commands:

mkdir express-typescript cd express-typescript npm init -y

Install project dependencies

With the package.json initialised, we can now install all of the dependencies required for the application to work. Reopen the terminal, navigate to the express-typescript directory, and run the following commands:

npm install cors dayjs dotenv express pino pino-pretty rimraf npm install @types/node @types/cors @types/express @types/pino ts-node-dev typescript -D

You will now be able to use all these packages in your project.


Initialise Typescript

Run the following command:

npx tsc --init

If this step is not working for you, there will be information on how to solve it here. Most likely, it is because you do not have TypeScript installed on your machine.

Create an Express JS app

Open up the express-typescript folder in your code editor, and create a file titled index.ts. Import the express package inside of this file using es6 syntax, then create the app. Finally, you need to tell the app which port to listen on.

//index.ts

import express from "express"; const port = process.env.PORT || 3000; const app = express(); app.listen(port, async () => { console.log(`app listening at port ${port}`); });

Create scripts for production and development

Open the package.json file you created and add the following scripts.

// package.json

"scripts": { "dev": "ts-node-dev --respawn --transpile-only index.ts", "build": "rimraf ./build && tsc", "start": "node build/index.js" }

You will also need to specify an output directory to match what was set in the scripts.

// tsconfig.json

"compilerOptions": { ... "outDir": "build", ... }

You will now be able to run your Express application using TypeScript.

Quality of Life changes & folder structure suggestion

Instead of making an index.ts file, you can make a src folder where your entire app will live. In this folder, you will have other folders which contain routes, middleware, controllers, and other utility functions. You will also have a file in the root of the src directory labeled app.ts, the entry point of your application, and another file titled routes.ts which will house a function that creates all the routes present in your application.

Your folder structure should now resemble this:

-node_modules

-src

--controllers

--middleware

--routes

--utils

--app.ts

--routes.ts

-package.json

-tsconfig.json

Inside the routes folder, you can create the routes for your application. I will use a user route as an example. Create a file titled user.routes.ts, and create a simple route.

// src/routes/user.routes.ts

import express from 'express'; export const userRoutes = express.Router(); userRoutes.get('/', (req, res) => { return res.send('I am a User') })

We will now move on to the routes.ts file located in the root of the src directory. We will create a routes function that accepts the express application as a parameter, and uses the application to create the routes.

//src/routes.ts

import { Express, Request, Response } from "express"; import { userRoutes } from "./routes/user.routes"; function routes(app: Express) { // check api to ensure working app.get("/healthcheck", (req: Request, res: Response) => { res.sendStatus(200); }); app.use("/api/users", userRoutes); } export default routes;

Inside the utils folder, you will create two files. One of which will be titled server.ts, which will be the file that creates your express server, and the other will be titled logger.ts, which will use the pino and dayjs libraries to make console log outputs look better, and easier to understand.

// src/utils/logger.ts

import logger from "pino"; import dayjs from "dayjs"; const log = logger({ transport: { target: "pino-pretty", }, base: { pid: false, }, timestamp: () => `, "time":"${dayjs().format()}"`, }); export default log;

// src/utils/server.ts

import express, { Express } from "express"; import cors from "cors"; import routes from "../routes"; function createServer(): Express { const app = express(); app.use(cors()); app.use(express.json()); routes(app) return app; } export default createServer;

With all of the setup done, we can now allow our application to begin listening on a specified port. This will be done inside the app file placed in the root directory of the src folder

// src/app.ts

import * as dotenv from "dotenv"; dotenv.config(); import connect from "./utils/connect"; import logger from "./utils/logger"; import createServer from "./utils/server"; const port = process.env.PORT || 3000; const app = createServer(); app.listen(port, async () => { logger.info(`app listening at port ${port}`); });

These changes will make your code easier to scale, manage, and understand. However, there is one more important detail that we must not forget. Updating our scripts to work with the changes we made.

// package.json

"scripts": { "dev": "ts-node-dev --respawn --transpile-only src/app.ts", "build": "rimraf ./build && tsc", "start": "node build/src/app.js" }

Conclusion

We can easily create an express js application with TypeScript by following a few simple steps:

  1. Create a project folder and initialise package.json
  2. Install project dependencies and types
  3. Initialise TypeScript
  4. Create an Express JS app
  5. Create scripts for production and development

source code