Why I choose NestJS over other Node JS frameworks
I am a big fan of NodeJS for its thin simplistic approach. I have been using Node.js since 2011–12 and Express has been my default framework of choice for quick prototyping or writing micro-service API. Over time I have played with some other Node.js frameworks like sails, koa, loopback, etc. Somehow end of the day I always had to come back to Express.
But from late 2018, I have been using NestJS and kind of feeling like: at last, I have found the right framework I have been looking for this long time. This post is about self-reasoning why I am choosing Nest over Express or other frameworks.
Highly opinionated Vs Un-opinionated framework
Express is an un-opinionated, minimalistic framework. Un-Opinionated frameworks highly trust the developers to make the right choice. It allows developers to choose whatever tools or technologies, middleware, hooks they want to use. Developers structure their codes without any specific structure that is forced by the framework.
Express being an un-opinionated framework does not come with any specific template engine, body-parser, error handler, etc. This is kind of good for a geek developer. I used to love this freedom. Every time I had to scaffold a new project, I used to decorate it with the tools of my own choice. But making a choice for a team is always difficult. If you have two other developers in your team, one might love ejs, the other might love blade as the template engine. And thus, every Express project eventually becomes a unique one.
Even within one big project, different micro-service team’s project structure and tooling becomes different. One cannot just jump from one micro-service team to another due to this.
And “freedom” is not something everyone deserves, I think. Un-opinionated frameworks allow developers to code anything anywhere. I have seen many messy projects with ugly project structures. I have seen many unnecessary design pattern heavy projects where more efforts given on unnecessary abstraction.
Nest is a highly opinionated framework. It follows the design paradigm “convention over configuration”. It strongly guide developers to use certain tools and to code in a certain way. Behind the scene it already wraps the controller with a try-catch block, already parse the request body, adds error handler, middleware, logger, etc. So, I do not need to do these common things every-time while scaffolding a new project. Developers have to write the controller, service, repositories in certain places in a certain way.
So, I think anyone familiar with the Nest can jump into a project without spending much time on how code is being organized or which tools are being used. Unless you are a developer who is super creative in writing messy code, code in a Nest project should be much more maintainable than in an un-opinionated Express project.
TypeScript
I know many JS developers do not like TypeScript. They can come up with some really strange logic. Like Typescript is a Microsoft product, so we cannot rely on it! Anyway, I believe Typescript is the sweetest thing introduced in the recent JavaScript renaissance.
With loosely typed languages like PHP, Python, or JavaScript developers might write a bunch of code quickly. But without strict typing, there is always a chance of creating bugs. As projects grow, you have to always go back to several service files or component files to check what methods are available or what parameters they are expecting. Most of the bugs are created when you are expecting a user object, but you passed a user id. Maybe you misspelled an object’s attribute name. Without type hinting, you have to spend hours & hours debugging this sort of silly mistake. And if you are a new developer and just joined a year-old project you will be just lost.
But with Typescript from request body to response — if we use strict typing, you can code a lot faster and chances of creating these sorts of silly bugs are reduced to near 0 %.
Nest is probably the only available well-structured framework that is written entirely with Typescript. Even though — you can use Typescript in Express (by some tweaking) but that is not 100% Typescript.
Use of Decorators, custom decorators
Decorators are a proposed feature of JavaScript. But Typescript already has this feature. All major backend frameworks of Java, Python, Php use decorators/annotations heavily. Decorators allow metadata programming, a mechanism for modifying classes, class members in a declarative fashion.
In NEST I can bind the controller to routes, set request method, inject request body or parse params, control auth/role guards beautifully with decorators. Whether an input attribute is required, whether to check email or whether to serialize an attribute into JSON or not — everything can be controlled with decorators.
/**
* A typical example of using different decorators in
* a nest controller method
*/@Get('/me')
@ApiBearerAuth()
@UseGuards(RolesGuard)
@Roles('user', 'admin')
@UseInterceptors(ClassSerializerInterceptor)
async getMe(
@AuthUser() user: IAuthUser,
): Promise<User> {}
Nest also provides an easy way to declare custom decorators. So, if any common task is there that can be used in different parts of my project, I can easily write it as a decorator and use it in multiple places.
Domain-Driven Development
Nest provides a way to define multiple modules under the one root module. Modules encapsulate providers, controller, repositories, interceptors, middleware, etc. With this, we can logically distribute the entire project’s code into logical domains. Unless a provider/service is defined within the same module it cannot be injected into a controller or service class. If we have to use a service from another module, that service needs to be exported and that module needs to include in this module. Through this, we can create domain wise clear boundaries, write reusable modules, and write loosely coupled and maintainable code.
Angular like architecture
A major reason for the growing Node.js popularity is using the same language in both back-end and front-end. Unfortunately, the only benefit we have been getting so far is the same syntax. Coding architecture, philosophy, terms — everything has been completely different.
Architecture wise NEST is heavily inspired by Angular. It’s a module, service, controller, pipe, decorators — everything’s syntax, usage, and philosophy exactly matches that of Angular. A frontend Angular developer can easily jump into the backend NEST project — feeling like working in the same project. With the same concept and philosophy for both backend and frontend without much time wasted in context switching.
Command-line interface (CLI)
Nest comes with its own CLI to initiate and scaffold a project quickly. With this, we can easily generate modules, controllers, pipes, and middlewares to ease a developer’s pain.
Testing
Nest CLI generated application starter comes with a default testing environment configured with Jest framework. Whenever we generate a service, controller, middle wire, interceptors, etc — CLI generates a “spec” file alongside with it. It provides auto-generated testing bed code, so developers don’t have to write the scaffolding code need for the unit test. So, writing unit testing becomes much easier with NestJs.
Performance
There are some threads in stack overflow where people are comparing a “hello world” performance benchmark between Express and Nest. Since Nest itself uses Express underneath, it’s really stupid to compare these two. To get a lot better performance, Nest gives an alternative way to change the underneath framework implementation from Express to Fastify (another node framework).
$ npm i --save @nestjs/platform-fastify
https://docs.nestjs.com/techniques/performance
Using Fastify we can get even better performance from Nest than a simple plain Express “hello world”.
You can get the performance benchmark report here.
Conclusion
NestJS is one of the most rapidly growing Node.js framework in 2018/2019. Till today (Aug 2019) it has 18k+ GitHub stars and over 91k weekly npm downloads. Being an Angular+TypeScript developer Nest was my obvious choice. But someone who is not familiar with TypeScript or Angular philosophy might find a bit difficult to getting started with it.
If you are not using Angular or Typescript, please give NestJS a go, I would like to know your view from a neutral position.
You can learn more about NestJS from its official site and documentation. Feel free to make your comment here or catch me on twitter @asad_rahman.
Visit our website to learn more about us:
www.monstar-lab.co.bd