Tutorial

How To Set Up a Node Project With Typescript

Updated on December 20, 2021
Default avatar

By Jordan Irabor

English
How To Set Up a Node Project With Typescript

Introduction

Node is a run-time environment that makes it possible to write server-side JavaScript. It has gained widespread adoption since its release in 2011. Writing server-side JavaScript can be challenging as a codebase grows due to the nature of the JavaScript language: dynamic and weak typed.

Developers coming to JavaScript from other languages often complain about its lack of strong static typing, but this is where TypeScript comes into the picture, to bridge this gap.

TypeScript is a typed (optional) super-set of JavaScript that can help with building and managing large-scale JavaScript projects. It can be thought of as JavaScript with additional features like strong static typing, compilation, and object oriented programming.

Deploy your frontend applications from GitHub using DigitalOcean App Platform. Let DigitalOcean focus on scaling your app.

Note: TypeScript is technically a super-set of JavaScript, which means that all JavaScript code is valid TypeScript code.

Here are some benefits of using TypeScript:

  1. Optional static typing.
  2. Type inference.
  3. Ability to use Interfaces.

In this tutorial you will set up a Node project with TypeScript. You will build an Express application using TypeScript and transpile it down to JavaScript code.

Prerequisites

Before you begin this guide, you will need Node.js installed on your system. You can accomplish this by following the How to Install Node.js and Create a Local Development Environment guide for your operating system.

Step 1 — Initializing the Project

To get started, create a new folder named node_project and move into that directory:

  1. mkdir node_project
  2. cd node_project

Next, initialize it as an npm project:

  1. npm init -y

The -y flag tells npm init to automatically say “yes” to the defaults. You can always update this information later in your package.json file.

Step 2 — Configuring the TypeScript Compiler

Now that your npm project is initialized, you are ready to install and set up TypeScript.

Run the following command from inside your project directory to install the TypeScript:

  1. npm install --save-dev typescript
Output
added 1 package, and audited 2 packages in 1s found 0 vulnerabilities

TypeScript uses a file called tsconfig.json to configure the compiler options for a project. Create a tsconfig.json file in the root of the project directory:

  1. nano tsconfig.json

Then paste in the following JSON:

tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "esModuleInterop": true,
    "target": "es6",
    "moduleResolution": "node",
    "sourceMap": true,
    "outDir": "dist"
  },
  "lib": ["es2015"]
}

Let’s go over some of the keys in the JSON snippet above:

  • module: Specifies the module code generation method. Node uses commonjs.
  • target: Specifies the output language level.
  • moduleResolution: This helps the compiler figure out what an import refers to. The value node mimics the Node module resolution mechanism.
  • outDir: This is the location to output .js files after transpilation. In this tutorial you will save it as dist.

To learn more about the key value options available, the official TypeScript documentation offers explanations of every option.

Step 3 — Creating a Minimal TypeScript Express Server

Now, it is time to install the Express framework and create a minimal server:

  1. npm install --save express@4.17.1
  2. npm install -save-dev @types/express@4.17.1

The second command installs the Express types for TypeScript support. Types in TypeScript are files, normally with an extension of .d.ts. The files are used to provide type information about an API, in this case the Express framework.

This package is required because TypeScript and Express are independent packages. Without the @types/express package, there is no way for TypeScript to know about the types of Express classes.

Next, create a src folder in the root of your project directory:

  1. mkdir src

Then create a TypeScript file named app.ts within it:

  1. nano src/app.ts

Open up the app.ts file with a text editor of your choice and paste in the following code snippet:

src/app.ts
import express from 'express';
const app = express();
const port = 3000;

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

app.listen(port, () => {
  return console.log(`Express is listening at http://localhost:${port}`);
});

The code above creates Node Server that listens on the port 3000 for requests. To run the app, you first need to compile it to JavaScript using the following command:

  1. npx tsc

This uses the configuration file we created in the previous step to determine how to compile the code and where to place the result. In our case, the JavaScript is output to the dist directory.

Run the JavaScript output with node:

  1. node dist/app.js

If it runs successfully, a message will be logged to the terminal:

  1. Output
    Express is listening at http://localhost:3000

Now, you can visit http://localhost:3000 in your browser and you should see the message:

  1. Output
    Hello World!

Open the dist/app.js file and you will find the transpiled version of the TypeScript code:

dist/app.js
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const express_1 = __importDefault(require("express"));
const app = (0, express_1.default)();
const port = 3000;
app.get('/', (req, res) => {
    res.send('Hello World!');
});
app.listen(port, () => {
    return console.log(`Express is listening at http://localhost:${port}`);
});
//# sourceMappingURL=app.js.map

At this point you have successfully set up your Node project to use TypeScript. Next you’ll set up the eslint linter to check your TypeScript code for errors.

Step 4 — Configuring Typescript Linting with eslint

Now you can configure TypeScript linting for the project. First, we install eslint using npm:

  1. npm install --save-dev eslint

Then, run eslint’s initialization command to interactively set up the project:

  1. npx eslint --init

This will ask you a series of questions. For this project we’ll answer the following:

  • How would you like to use ESLint?: To check syntax and find problems
  • What type of modules does your project use?: JavaScript modules (import/export)
  • Which framework does your project use?: None of these
  • Does your project use TypeScript?: Yes
  • Where does your code run?: Node
  • What format do you want your config file to be in?: JavaScript

Finally, you will be prompted to install some additioanl eslint libraries. Choose Yes. The process will finish and you’ll be left with the following configuration file:

eslintrc.js
module.exports = {
  env: {
    es2021: true,
    node: true,
  },
  extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended'],
  parser: '@typescript-eslint/parser',
  parserOptions: {
    ecmaVersion: 13,
    sourceType: 'module',
  },
  plugins: ['@typescript-eslint'],
  rules: {},
}

Run the linter to check all files with the .ts TypeScript extension:

  1. npx eslint . --ext .ts

You’ve now set up the eslint linter to check your TypeScript syntax. Next you’ll update your npm configuration to add some convenient scripts for linting and running your project.

Step 5 — Updating the package.json File

It can be useful to put your commonly run command line tasks into npm scripts. npm scripts are defined in your package.json file and can be run with the command npm run your_script_name.

In this step you will add a start script that will transpile the TypeScript code then run the resulting .js application.

You will also add a lint script to run the eslint linter on your TypeScript files.

Open the package.json file and update it accordingly:

package.json
{
  "name": "node_project",
  "version": "1.0.0",
  "description": "",
  "main": "dist/app.js",
  "scripts": {
    "start": "tsc && node dist/app.js",
    "lint": "eslint . --ext .ts",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "@types/express": "^4.17.1",
    "@typescript-eslint/eslint-plugin": "^5.4.0",
    "@typescript-eslint/parser": "^5.4.0",
    "eslint": "^8.3.0",
    "typescript": "^4.5.2"
  },
  "dependencies": {
    "express": "^4.17.1"
  }
}

In the snippet above, you updated the main path to be the compiled app output, and added the start and lint commands to the scripts section.

When looking at the start command, you’ll see that first the tsc command is run, and then the node command. This will compile and then run the generated output with node.

The lint command is the same as we ran in the previous step, minus the use of the npx prefix which is not needed in this context.

Conclusion

In this tutorial, you learned about why TypeScript is useful for writing reliable JavaScript code. You also learned about some of benefits to working with TypeScript.

Finally, you set up a Node project using the Express framework, but compiled and ran the project using TypeScript.

DigitalOcean provides multiple options for deploying Node.js applications, from our simple, affordable virtual machines to our fully-managed App Platform offering. Easily host your Node.js application on DigitalOcean in seconds.

Learn more here


About the authors
Default avatar
Jordan Irabor

author

Still looking for an answer?

Ask a questionSearch for more help

Was this helpful?
 
9 Comments


This textbox defaults to using Markdown to format your answer.

You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!

how can I deploy this tho?

This post is really helpful to get a good understanding of the different components. One can setup a new Node.js and Typescript project step by step but using this Github project template brings a fully composed project clone with support for building, linting, testing, CI and more https://github.com/alexandervantrijffel/ts-node-project-template

While this tutorial helped me get things up and running (thanks!), I also noticed that several things about it are outdated. Maybe it’s a good idea to decouple some of the tooling – both Express and the linter are separate issues from the intent of using Node with TS, after all.

TSLint is deprecated and ESLint should be used instead now. I recommend running eslint --init before setting up the linting rules.

The web server code itself will give linting errors because the app.listen() callback function does not expect any arguments. So err can’t be passed and err would have to be given a type anyway (this is TypeScript, after all!).

Great article it was very helpful

this does not compile, it throws an error at the app.listen line in app.ts

Argument of type '(err: any) => void' is not assignable to parameter of type '() => void'.

fyi, TSLint has been deprecated as of 2019.

Thank you, very useful article for newbie in ts.

Thank you!, The only thing is that the tslint is depreciated… But I must admit eslint is not as easy setup imho… However if that could be covered the next version of this article would be nice.

This is by far one of the cleanest tutorials for getting a express server up with typescript. Very well done Jordan. I would suggest adding the keyword express to your title.

Cheers

Try DigitalOcean for free

Click below to sign up and get $200 of credit to try our products over 60 days!

Sign up

Join the Tech Talk
Success! Thank you! Please check your email for further details.

Please complete your information!

Get our biweekly newsletter

Sign up for Infrastructure as a Newsletter.

Hollie's Hub for Good

Working on improving health and education, reducing inequality, and spurring economic growth? We'd like to help.

Become a contributor

Get paid to write technical tutorials and select a tech-focused charity to receive a matching donation.

Welcome to the developer cloud

DigitalOcean makes it simple to launch in the cloud and scale up as you grow — whether you're running one virtual machine or ten thousand.

Learn more
DigitalOcean Cloud Control Panel