skip to content
Eduim

Setup Express.js app with typescript

/ 4 min read

Start your express project with typescript boilerplate

Express.js is a popular web application framework for Node.js that simplifies the process of building robust and scalable web applications based on the middleware architecture. It provides a minimalistic and flexible set of features for creating web servers and handling HTTP requests and responses.

There are several tools that provide a boilerplate app but rarely an Express server with TypeScript, today we are going to start one from scratch.

Package.json and test index.js

We start creating a new folder where the whole server is going to be. And we execute yarn init to create the package.json. You should end up with something like this:

{
	"name": "server",
	"version": "1.0.0",
	"main": "index.js",
	"license": "MIT"
}

Now we can try to create a index.js and insert a simple console.log(‘hello world’), to test it we first need to add nodemon with yarn add —dev nodemon and then add to the package.json a new script and display the log when we execute it.

"scripts": {
  "dev": "nodemon index.js"
}

Create minimal Express server

Let’s add express with yarn add express and add the following code at index.js

const express = require("express");

const app = express();
const port = 8080;

app.get("/", (req, res) => {
	res.send("Express + TypeScript Server");
});

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

We can add .env and .env.example files to start using environment variables. Create the previous files and add PORT=8080 to them. If we want to read the environment variables we need to add the dotenv package yarn add dotenv and a few lines to the express server, the file should look like:

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

dotenv.config();

const app = express();
const port = process.env.PORT;

app.get("/", (req, res) => {
	res.send("Express + TypeScript Server");
});

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

Installing typescript to the server

Time to start TypeScript, we’ll need to install it along with all the types for Express and Node.js with yarn add --dev typescript ts-node @types/express @types/node @types/dotenv. Once it’s installed we need to create the configuration file for TypeScript, run the following yarn tsc --init and after that will appear a tsconfig.json in the directory.

Now we should have the file with the default config.

  • target: Set the JavaScript language version for emitted JavaScript and include compatible library declarations.

  • module: Specify what module code is generated.

  • esModuleInterop: Emit additional JavaScript to ease support for importing CommonJS modules. This enables ‘allowSyntheticDefaultImports’ for type compatibility.

  • forceConsistentCasingInFileNames: Ensure that casing is correct in imports.

When TypeScript complies the code the outDir is going to define where is going to be the final code, let’s set it to /dist folder. We also can change several options, change the following options in your file.

{
	"ts-node": {
		"files": true
	},
	"compilerOptions": {
		"outDir": "./dist",
		"moduleResolution": "node",
		"rootDirs": ["node_modules", "test"],
		"typeRoots": ["node_modules/@types", "types"],
		"noUnusedLocals": true,
		"noUnusedParameters": true
	},
	"include": ["src/**/*", "test/**/*", "types/**/*"],
	"exclude": ["node_modules", ".vscode"]
}

Now, let’s change the Express server to TypeScript. Start by renaming index.js to index.ts

import express, { Express, Request, Response } from 'express';
import dotenv from 'dotenv';

dotenv.config();

const app: Express = express();
const port = process.env.PORT;

app.get('/', (_: Request, res: Response) => {
  res.send('Express + TypeScript Server');
});

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

Make sure to change dev and instead of running index.js run index.ts

Eslint and Prettier

We need to add a cuple of packages that are going to help us to maintain the code clean, eslint and prettier. Add them with yarn add --dev @typescript-eslint/parser @typescript-eslint/eslint-plugin eslint and create the .eslintrc.json file with the following config:

{
	"env": {
		"browser": true,
		"es2021": true
	},
	"extends": [
		"eslint:recommended",
		"plugin:@typescript-eslint/recommended",
		"plugin:prettier/recommended"
	],
	"overrides": [],
	"parser": "@typescript-eslint/parser",
	"parserOptions": {
		"ecmaVersion": "latest",
		"sourceType": "module"
	},
	"plugins": ["@typescript-eslint", "prettier"],
	"rules": {}
}

We’ll need a .prettierrc file with the following config and the package to avoid conflicts with esLint yarn add --dev prettier eslint-plugin-prettier

{
	"trailingComma": "es5",
	"tabWidth": 2,
	"semi": false,
	"singleQuote": true
}

And finally make sure we ignore secret and build files in the .gitignore

.DS_Store
*node_modules*
dist
*dist
.env

That’s it, this is my personal choice but there are a lot of options specially for the tsconfig.json file, there is a repo where you can check out several options depending on the project you are working on.