These days for all serious Node JS projects, it’s recommended to use TypeScript. With TypeScript, VS Code offers a lot of powerful refactoring features. These features are especially useful in large projects where you want to be sure that you are not breaking existing code while refactoring.

Set up Node and Express JS project from scratch

In this tutorial we will see how to set up a Node and Express JS project with TypeScript, ESList and Prettier. ESLint makes sure that the code is written in consistent style and Prettier gives nice formatting without a lot of effort from your side. Both of these features are very important when multiple developers work on the same project.

To get started follow these steps, to create a Node JS project:

mkdir backend
cd backend
npm init -y

Now let’s set up TypeScript, ESLint and Prettier.

npm install --save-dev @types/node @typescript-eslint/eslint-plugin \
@typescript-eslint/parser eslint eslint-config-prettier eslint-plugin-import \
eslint-plugin-prettier prettier ts-node typescript

File: tsconfig.json

{
  "compilerOptions": {
    "target": "es6",
    "lib": ["es5", "es6", "dom"],
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "baseUrl": "src/",
    "typeRoots": ["./src/types", "./node_modules/@types"],
    "resolveJsonModule": true,
    "outDir": "./dist",
    "removeComments": true,
    "allowSyntheticDefaultImports": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "skipLibCheck": true
  },
  "include": ["./src/**/*.tsx", "./src/**/*.ts"],
  "exclude": ["node_modules", "test/**/*.ts"]
}

File: .eslintrc

{
    "parser": "@typescript-eslint/parser",
    "extends": [
        "plugin:@typescript-eslint/recommended",
        "prettier"
    ],
    "plugins": ["prettier"],
    "parserOptions": {
        "ecmaVersion": 2018,
        "sourceType": "module"
    },
    "rules": {
        "prettier/prettier": "error"
    }
}

File: .prettierrc.json

{
  "tabWidth": 2,
  "semi": false,
  "singleQuote": true,
  "trailingComma": "none",
  "printWidth": 120
}

Create the src folder and index.ts file to it.

mkdir src

File: src/index.ts

console.log("Hello World");

VS Code should show you errors from Prettier and ESLint. Now let’s create the npm scripts to run ESLint and Prettier.

File: package.json

...
    "scripts": {
        "lint": "eslint src/**/*.ts",
        "format": "eslint src/**/*.ts --fix"
    },
...

Now you can run `npm run format` and `npm run lint` to format the code and check for the linting issues.

Let’s install nodemon and add the scripts to run the project in dev and prod mode.

npm install --save-dev nodemon

For nodemon we need to create the nodemon.json settings file.

File: nodemon.json

{
    "ext": ".ts, .js, .yaml"
}

This tells nodemon to watch for typescript, javascript and yaml files for changes to reload the project.

File: package.json

...
"scripts": {
    "build": "npx tsc",
    "start": "TZ='UTC' node dist/index.js",
    "dev": "TZ='UTC' nodemon src/index.ts",
    "lint": "eslint src/**/*.ts",
    "format": "eslint src/**/*.ts --fix"
},
...

Here note that we are setting the TZ='UTC' environment variable before running the node command. This ensures that the node process uses UTC timezone rather than using your machine’s timezone. It’s important to run your server process with UTC timezone. This ensures that you can deal with users from multiple time zones easily.

Now to run in production mode:

npm run build
npm run start

To run in dev mode:

npm run dev

You should see the text “Hello World” printed on the console.

Now let’s add Express JS to the project.

npm install --save express body-parser

npm install --save-dev @types/express

Let’s add the route to our index file:

File: src/index.ts

import express, { Express, Request, Response } from 'express'
import bodyParser from 'body-parser'

const app: Express = express()

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())

app.get('/', (req: Request, res: Response) => {
  res.json({ message: 'Hello World!' })
})

app.listen(8080, async () => {
  console.log('Server is running at http://localhost:8080')
})

Start the project with

npm run dev

Then access the API using curl command:

curl --location --request GET 'http://localhost:8080/'

It should print the following output:

{"message":"Hello World!"}

That’s it. Now we have an Express JS project running with TypeScript. Hopefully this will help you to get started with TypeScript in your next Node JS project.

To download the finished project source code, please click here.

Author's Bio:

mobisoft-pritam
Pritam Barhate

Pritam Barhate, with an experience of 14+ years in technology, heads Technology Innovation at Mobisoft Infotech. He has a rich experience in design and development. He has been a consultant for a variety of industries and startups. At Mobisoft Infotech, he primarily focuses on technology resources and develops the most advanced solutions.