How to set up an Express.js project with TypeScript
Tags: javascript, webdev, typescript, node
Published: 2022-12-08 00:12:10


Express is a minimal and flexible Node.js web application framework that provides a robust set of features for web and mobile applications. Honestly, I haven’t been using it for quite some time, but now I want to update my old experience with Express.js and a TypeScript setup. Besides, Express.js version 5 (beta) is now available and maybe in future articles, I’ll share my thoughts and experience about it. But today, we’re going to create a setup with TypeScript and Express.js with an easy-to-use folder structure. And the first thing we need is to generate an Express.js project.

## Generate Express.js project

As a first step, we need to have Node.js itself installed on the machine. Open a terminal and type ‘node -V’ and if it shows you a version, you’re good to go. For those who see an error, please follow [the link](https://nodejs.org/en/download/), download the Node.js LTS version, and install it by following the instructions on the site.

Next, create a folder where you want to have your project. You can name it whatever you want. For the example let’s name it ‘server’.

Open your terminal and past the commands below and run them one after another:

    # Navigate to the folder you're going to have you project in
    cd ~/path/to/any/folder/you/re/going/to/have/your/project/in

    # Generate in that folder a new folder with name 'server'
    mkdir server
    # Initialize a package.json file with default values
    npm init --yes

After executing these 3 commands, you’ll have a package.json file which is going to look like this:

    {
      "name": "work",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "directories": {
        "test": "test"
      },
      "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
      },
      "keywords": [],
      "author": "",
      "license": "ISC"
    }

And now, let’s add Express.js to the project by running the command:

    npm install express

It will generate a package-lock.json file and a node_modules folder in the server folder. And also, in the package.json file, a new block “dependencies” with express.js will appear.

![1](https://cdn-images-1.medium.com/max/2724/0*LKWwZF9kMHn1Qyxk)

## Create a Hello World server app with Express.js

Creating a simple server with Express.js is a 3 steps deal:

 1. Import express.js from the modules

 2. Define routes

 3. Turn on express.js to listen to a specific port.

Take a look at the picture, can you identify each step on your own?

![2](https://cdn-images-1.medium.com/max/2000/0*T1S20TzAE9jWe5Xz)

Let’s start from the start. Go to the ‘server’ folder and create a new file index.js which is going to be the entry point (the file node.js is going to run first) where we are going to put our server’s configuration.

1. Now, let’s import express.js from the modules

    const express = require("express");
    const app = express();

2. Define one route which is going to respond to a GET request to the [http://localhost:8080/](http://localhost:8080/) URL with the text “Hello world!” as a response.

    app.get("/", (req, res) => {
        res.send("Hello world!");
    });

3. Turn on express.js to listen to port 8080

    app.listen(8080, () => {
        console.log(`server started at http://localhost:${8080}`);
    });

And that’s it. Our Node.js server with Express.js is ready. But how can we run it? That’s where we would ask Node.js to help us. Open your terminal and run the command

    node index.js

This command will tell Node.js to run our index.js file with the Express.js server and when it’s done, you should the console.log we declared in step 3

![3](https://cdn-images-1.medium.com/max/2000/0*3W1nIf7Ehns0KS9p)

And if you would open your browser at [http://localhost:8080](http://localhost:8080/) you’ll see the text “Hello world!” we declared in step 2.

![4](https://cdn-images-1.medium.com/max/2156/0*KfpzU46MKSaZTkx6)

But wait a minute, should we run this ‘node index.js’ command from the terminal each time? Of course not. Besides, this command is gonna be much longer with TypeScript support, so let’s place it in the package.json file:

![5](https://cdn-images-1.medium.com/max/2660/0*5XbylcD0MqlVgZjf)

The dot instead of index.js as before is just a shortcut for an index file in the folder. So now, we just need to run npm run start and everything is going to work as before.

As we have our express.js up and running, let’s add TypeScript support, because we’re great developers and want to have types to protect ourselves from ourselves :)

**If you’re going to make changes, to this setup, you would need to restart your server manually via the terminal. At the end of the article, I’ll put a Bonus section on how to fix that.**

## Add TypeScript Support

Since we’re in the world of Node.js, I mean, in the Node.js environment, and it only understands the JavaScript language, the TypeScript code needs to be transpiled to JavaScript before the app is used in runtime. And for that we’re going to use ts-node which transforms TypeScript into JavaScript, enabling you to directly execute TypeScript on Node.js without precompiling.

The first step we need to install the typescript and ts-node packages, but since it’s only the development-related packages we would add the -D flag which indicates that the packages are going to be installed for development mode and will be deleted on production.

    npm install typescript ts-node -D

Each time I install packages I’d like to verify it was added successfully to the package.json file. This time, packages should be added to the “devDependencies” section

![6](https://cdn-images-1.medium.com/max/2322/0*3VhlobF3q2fpzNBq)

Now, we need to configure the TypeScript. To do that, we need to create a ‘tsconfig.json’ file in the ‘server’ folder and put the following config there:

    {
      "compilerOptions": {
        "module": "commonjs",
        "target": "es6",
        "rootDir": "./",
        "esModuleInterop": true
      }
    }

It’s just a basic config, and the information about all properties you can find in the [official TypeScript documentation](https://www.typescriptlang.org/docs/).

Now, we can change the extension of the main file from index.js to index.ts.

Open the package.json file and update the “main” property as well from js to ts.

And the last step is to update our “start” script. Instead of “node” we’re going to use “ts-node” now. As simple as that.

![7](https://cdn-images-1.medium.com/max/2000/0*AaeUZ13LBaTnRksn)

Now we can run our server with the same “npm run start” command and open the [http://localhost:8080](http://localhost:8080/) and we’ll see the text “Hello world!” as before. But what now?

Now we can use types. For the express.js project, we only need to add support for node.js and express.js types. We can install it as a dev dependency with the command:

    npm install @types/node @types/express -D

(Don’t forget to verify that they were added successfully to the package.json “devDependencies” section)

Now, we can use types with the latest ES6 features like imports. Let’s update our index.js code with a TypeScript version

    import express, { Request, Response } from 'express'
    
    const app = express();
    
    app.get("/", (req: Request, res: Response) => {
        res.send( "Hello world!" );
    });
    
    app.listen(8080, () => {
        console.log(`server started at http://localhost:${8080}`);
    });

As you see, now, since we have specific types of requests and responses that come from the ‘express’ module (actually from the @types/express) we can be sure of what types we’re using across our server application. And also we can now see all things our variables support all thanks to TypeScript

![8](https://cdn-images-1.medium.com/max/2930/0*llZ7zQOeZD5eoLaX)

## Bonus

As I promised, the bonus part is going to be about watching mode. Developing apps without hot-reloading is a sin in the IT world (and I saw a lot of examples of projects even with senior developers on them). You should not waste your time in such a way. Besides, it’s not that hard to fix it. All you need is to use a nodemon package.

Since we only need it in development mode let’s put the -D flag when installing

    npm install nodemon -D

When it’s done, add a new serve command to the package.json file

    "serve": "nodemon index.ts"

At the end the “package.json” should look like this:

![9pm ](https://cdn-images-1.medium.com/max/2000/0*F9px_BqEGfEx7jps)

And now, you can run the server with hot-reloading

    npm run serve

![10](https://cdn-images-1.medium.com/max/2004/0*khojZImzFNlGoWEt)

As you see, it’s watching for extensions .ts and .json. That means if any files in the server folder with that extension would be updated the nodemon will automatically rebuild them and so you can now focus on the development process and don’t be distracted by restarting the server after changing a file.

Congratulations, you made it. This one was a bit longer than I expected. Please subscribe so you don't miss the next article, and feel free to contact me if you have any questions.

[Twitter](https://twitter.com/kucherenko_web) | [LinkedIn](https://www.linkedin.com/in/sergey-kucherenko/)