NodeJS: Enterprise architecture — Chapter 1


  • Create our first simple application
  • Use TypeScript and get acquainted with its syntax
  • Dive into app architecture principles
  • Write a real-world application in NestJS
  • Deploy it using Docker

What do you need to know to feel comfortable during reading? Just basic JavaScript knowledge. So, let’s start!

Chapter 1 — Why TypeScript?

Good and bad

  • Syntax highlights and autocomplete in IDE, then will save you from bugs and speed up your development.
  • The code is much easier to maintain and test that is valuable in large enterprise applications.
  • Refactoring! You can do it with a blink of an eye and do not afraid to break your code.

Secondly, it implements main object-oriented concepts, such as inheritance, encapsulation, and polymorphism.
And the last but not least — it is a superset of JavaScript. It simplifies
entry threshold and do not break javascript patterns like Dart.

But for every feature, we have to pay. In this case, you will pay with your time because you have to write more code. You need an interface for every object, type for any variable, parameter or function return. And if you are using libraries that don’t have types, you have to write it yourself. But in some cases, you can cheat and use any type.

Installation and environment setup

npm init

Here we enter package name, version, author and description. This command creates us package.json file with basic info. All our app dependencies will be stored here. Now we install typescript globally:

npm i -g typescript

And in your app dependencies we install NodeJS types so we can use it in your app:

npm i @types/node --save-dev

In order to compile TS to JS we need to tell TypeScript how do we want to do that, where do we want output js files or which ECMAScript target version. We need tsconfig.json file which indicates that this is a root directory for our typescript project. I will explain every compile option that we will use, but this knowledge is not very important for a start:

“compilerOptions”: {
“module”: “commonjs”, // Specify module code generation
“declaration”: false, // Do I generate d.ts files?
“noImplicitAny”: false, // Do I raise an error on expressions and declarations with an implied any type?
“removeComments”: true, // Remove all comments from bundle
“noLib”: false, // Do i exclude lib.d.ts?
“allowSyntheticDefaultImports”: true, // Do I allow default imports from modules with no default export?
“emitDecoratorMetadata”: true, // Necessary for decorators
“experimentalDecorators”: true, // Necessary for decorators
“target”: “es6”, // Specify ECMAScript target version
“sourceMap”: true, // Do I generate .map files for debugging?
“outDir”: “./dist”, // Ouput path
“baseUrl”: “./src” // Base directory to resolve non-relative module names
“include”: [
“src/**/*” // Which files to include
“exclude”: [
“node_modules” // Which files to exclude

Simple app example

mkdir src
cd src
touch index.ts

Then we will add some code, that creates hamster:

Here we declared hamster class and initialized it, passing some process variables like its name and age. Then we call `introduce` function that makes our new friend introduce itself. We use 2nd and 3rd process argument because 0 is node path and 1st is a file path.


And what if we write the same code in JS (es6)?

Is you can see, we had to write more code in TypeScript. Here we declared types of all variables, parameters and returns. For now on VSCode will gracefully promt all parameters and theres type when we create new hamster:

While refactoring we can swap variable name within one click not afraid to break the code:

Or find a class or other object definition from any file:

In this particular example benefits are not so obvious, but in large projects, this will save you a lot of time.

But we got distracted. Let’s get back to our hamster project and finally run it.

Run with tsc


We will get compiled js file and .map file in dist directory.

Then run it:

node dist/index.js Alfred 34

We got output I am Alfred and I am 34 years old. I recommend using this way in production.

Run with node-ts


npm i ts-node --save-dev
npm i typescript --save-dev

You can install it globally, but it is not recommended by its author.
Besides local typescript installation makes your project more stable, so you do not have to worry about TypeScript updates and different versions on other developer machines. Now we can run it without compilation:

./node_modules/.bin/ts-node src/index.ts Alfred 34


I will appreciate any feedback or 👏, so I’ll understand that this is useful for you.

IT Director in car selling company. In love with TypeScript, NodeJS and Angular.