Set up NodeJS Project with ExpressJS using TypeScript
Tags: typescript, express, beginners, tutorial
Published: 2023-04-24 10:24:44

## System requirements

- Node.js
- npm
- MacOS, Windows, and Linux are supported

## Create a project

Start by creating a folder called myapp (you can name it according to your project).

Navigate into the newly created folder and run the command `npm init --yes` to create a `package.json` file.

```terminal
$ mkdir myapp
$ cd myapp
$ npm init --yes
```

With the `--yes` flag, you will select the default configuration for npm. This is the package.json file after running the command:

```json
// package.json

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

Next, we will install Express and TypeScript using the following install command:

```terminal
$ npm install -s express
$ npm install -D typescript @types/express @types/node ts-node-dev
```

With `-s` or `--save`, the libraries will be noted in the dependencies section of the `package.json` file. Similarly, with `-D` or `--save-dev`, the libraries will be noted in the devDependencies section.

After that, we need to run the command to configure TypeScript for the project:


```terminal
npx tsc --init
```

This will create a `tsconfig.json` file in your project directory with the following content:

```json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    "outDir": "dist",
    "rootDir": "./",
    "strict": true,
    "esModuleInterop": true,
    "skipLibCheck": true
  }
}
```

Next, we create a `src` folder to contain our code, and create an `app.ts` file to set up the server for our code:

```typescript
// src/app.ts

import express, { Application, Request, Response } from "express";

class App() {
    private readonly app: Application;
    private readonly port: string | number;

    constructor() {
        this.app = express();
        this.port = process.env.PORT || 8080;
        this.setup();
    }

    public async setup() {
        this.app.use(express.json());
        this.app.use(express.static("public"));
    }

    public start() {
        this.app.listen(this.port, () => {
            console.log(`⚡️[server]: Server is running at http://localhost:${this.port}`);
        })
    }
}
```

Next, we will create a Controller by creating a `controllers` folder, and then creating a `controller.ts` file.

```typescript
// src/controllers/controller.ts

import express from "express";

interface Controller {
    setupRoutes(app: express.Application): void;
}

export default Controller
```

```typescript
// src/controllers/hello.controller.ts

import { Application, Router, Request, Response, NextFunction } from "express";
import Controller from "./controller";

export class HelloController implements Controller {
    private readonly router: Router;
    private readonly path: string;

    constructor(app: Application) {
        this.path = '/';
        this.router = Router();
        this.setupRoutes(app);
    }

    public hello = async (req: Request, res: Response, next: NextFunction) => {
        return res.send("Hello world!!!");
    }

    setupRoutes(app: Application): void {
        this.router.get(`${this.path}`, this.hello);
        app.use('/', this.router);
    }

}

export default HelloController;
```

Add Controller to `app.ts` file

```typescript

// src/app.ts

public async setup() {
    //...
    await this.setupController();
}

public async setupController() {
    new HelloController(this.app);
}
```

Here is the complete content of the `app.ts` file:

```typescript
import express, { Application, Request, Response } from "express";
import HelloController from "./controllers/hello.controller";

class App {
    private readonly app: Application;
    private readonly port: string | number;

    constructor() {
        this.app = express();
        this.port = process.env.PORT || 8080;

        this.setup();
    }

    public async setup() {
        this.app.use(express.json());
        this.app.use(express.static("public"));
        await this.setupController();
    }

    public async setupController() {
        new HelloController(this.app);
    }

    public start() {
        this.app.listen(this.port, () => {
            console.log(`⚡️[server]: Server is running at http://localhost:${this.port}`);
        })
    }
}

export default App;
```

Next, we will create an `index.ts` file outside the `src` folder to start the application:

```typescript
import App from './src/app';

const app: App = new App();
app.start();
```

Finally, we need to update the `package.json` file:

```json
"start": "node dist/index.js",
"dev": "ts-node-dev index.ts",
"build": "tsc"
```

Good luck!!!