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 runningindex.js
runindex.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.