Cover photo by Mateusz Wacławek
FeathersJS released its 5th major version, a.k.a Dove recently, and I've been watching the framework for some time. It is an excellent time to compare two backend framework giants, FeathersJS and NestJS. These are not your "yet another javascript framework" type of framework. They pave the way to backend development in the Node.js environment.
In my opinion, Node.js provides a very powerful backend software development environment. A typical backend application accepts requests, executes queries on the database, and writes some files to disk. All of these tasks can be handled asynchronously in Node.js, meaning the server can handle many requests at the same time. Even though you can achieve the same or better results in other languages, it is easier to write asynchronous code in Javascript.
The struggle in the Node.js world is standardization. You have too many options to choose from, due to the large number of npm packages and the community size. You can find new javascript framework releases every other week, or someone in the community sharing their way of building applications. Don't get me wrong, I'm happy to be in such an active community but this is a double-edged sword.
FeathersJS and NestJS both provide a structure for writing backend applications with their techniques. Both of them are capable of creating the same applications however their style differs a lot.
In this post, I will be comparing FeathersJS and NestJS from a developer experience perspective on key areas.
Application Structure
Application Structure - FeathersJS
To create a new FeathersJS application, execute this in your terminal: npm create feathers
In the application creation process, FeathersJS CLI allows for many customizations such as:
- Use
TypeScript or JavaScript
- Use
KoaJS or Express
, - Will you build a
REST application, Real-time application or all off them
- Which package manager to use
npm, yarn, pnpm
- What is your preferred schema definition format
TypeBox or JSON Schema
- Which databases will you connect to
SQLite, MongoDB, PostgreSQL, MySQL/MariaDB, MicrosoftSQL
- Select authentication mechanisms
Email + Password, Google, Facebook, Twitter, Github and Auth0
feathers-app/
├── config/
│ ├── custom-environment-variables.json
│ ├── default.json
│ └── test.json
├── knexfile.ts
├── migrations/
│ ├── 20230205130353_user.ts
│ └── 20230205130403_authentication.ts
├── package-lock.json
├── package.json
├── public/
│ └── index.html
├── readme.md
├── src/
│ ├── app.ts
│ ├── authentication.ts
│ ├── channels.ts
│ ├── client.ts
│ ├── configuration.ts
│ ├── declarations.ts
│ ├── hooks/
│ │ └── log-error.ts
│ ├── index.ts
│ ├── logger.ts
│ ├── services/
│ │ ├── index.ts
│ │ └── users/
│ │ ├── users.class.ts
│ │ ├── users.schema.ts
│ │ ├── users.shared.ts
│ │ └── users.ts
│ ├── sqlite.ts
│ └── validators.ts
├── test/
│ ├── app.test.ts
│ ├── client.test.ts
│ └── services/
│ └── users/
│ └── users.test.ts
└── tsconfig.json
FeathersJS application folder structure, automatically generated by CLI
FeathersJS application folder structure allows developers to easily decide where to put new files. It is well-structured and easily recognizable.
FeathersJS's preferred style of writing applications revolves around the idea of services. If you want to introduce new functionality in your application, you are most likely going to create a new service in FeathersJS.
Other than that, core functionalities such as authentication, routing, logging, and validation are well-defined in FeathersJS. You are very likely to use existing solutions provided by the framework with little configuration.
One thing that makes FeathersJS special is, it can generate its client code automatically. This is a unique feature I've never heard before - correct me if I am wrong on this.
Another special feature of FeathersJS is that it has the concept of channels. Which allows clients or other servers running your code to get notified about certain events. It is almost an in-app message broker on the server side. I'm not sure about the scalability of channels though! This is a very neat feature considering FeathersJS calls itself: The API and Real-time
Application Framework.
Least but not least, you can replace almost all 3rd party npm packages in FeathersJS to your taste. You might want to use another validation library or logging library, BUT you will never want to worry about your HTTP server library. FeathersJS HTTP server works fast and its performance is not dependent on the underlying HTTP server, read more about this here: Lightning Fast Routing
Application Structure - NestJS
To create a new NestJS application, execute this on your terminal: nest new my-project
NestJS doesn't provide many customizations through CLI but it has guides for customizations such as switching HTTP adapters.
nest-app/
├── README.md
├── nest-cli.json
├── package-lock.json
├── package.json
├── src/
│ ├── app.controller.spec.ts
│ ├── app.controller.ts
│ ├── app.module.ts
│ ├── app.service.ts
│ ├── main.ts
│ └── user/
│ ├── dto/
│ │ ├── create-user.dto.ts
│ │ └── update-user.dto.ts
│ ├── entities/
│ │ └── user.entity.ts
│ ├── user.controller.spec.ts
│ ├── user.controller.ts
│ ├── user.module.ts
│ ├── user.service.spec.ts
│ └── user.service.ts
├── test/
│ ├── app.e2e-spec.ts
│ └── jest-e2e.json
├── tsconfig.build.json
└── tsconfig.json
NestJS application folder structure, automatically generated by CLI
NestJS has a very modular project structure which is also reflected in its folder structure.
NestJS's preferred style of writing applications revolves around the idea of modules. Modules contain providers and controllers, they can import other modules or export their providers, and they are configurable, read more about it in the previous post: Best Way to Create Dynamic Modules in NestJS.
The business logic of a NestJS application usually resides in services. A service can use other services via dependency injection.
Implementation details of the NestJS framework are mostly hidden from the developers. NestJS exposes most of its functionality via Typescript decorators. If you are into code aesthetics you can prefer this style of coding, and read more about it in the previous post: Custom Decorators in NestJS
Since NestJS doesn't allow much customization it is easy for other NestJS developers to adapt your project easily.
A unique approach NestJS brings to backend application development is using reactive programming for most things. You can see Observables being used in HTTP requests, events, commands anything you name. This might be an innovative approach but in my experience, observables cause a performance drop in NestJS applications.
Similar to FeathersJS, core functionalities are well-defined and you can find resources for whatever you want to do in a NestJS application. NestJS can be considered a little more mature compared to FeathersJS.
NestJS is also customizable but due to the way adapters are written, sometimes using a different package can cause a loss of functionality. For example, it is known that you lose functionality by switching from Express Adapter to Fastify Adapter, but this is a minor inconvenience for most developers.
Last but not least, NestJS CLI is capable of managing a monorepo project structure. Which is very helpful if you are doing microservices with NestJS.
Customization Options
Customization Options - FeathersJS
FeathersJS is intentionally made to be very customizable. There are two reasons for that.
Firstly, if you are already developing your backend application in ExpressJS, you can just switch ExpressJS with FeathersJS and your project will work just fine. From there on, you can make the full switch bit by bit. This allows an easier migration path for projects that use ExpressJS.
Secondly, FeathersJS doesn't want to have opinions about how you implement your application. Rather, it aims to lay out best practices and its own implementations for them. It has good solutions that work well, and you can use them whenever you want to.
Customization Options - NestJS
NestJS is intentionally made to be less customizable.
NestJS aims to be the framework for enterprise applications. Enterprises don't like custom solutions. Custom solutions are costly to enterprise because it requires the knowledge of the person who implemented them. Developers can come and go, the project shouldn't be affected by this.
Also, we shouldn't forget NestJS is heavily inspired by AngularJS and it is also one of the less customizable frameworks for frontend.
BUT, this doesn't mean you can't customize your project or every other NestJS developer can immediately start working on existing NestJS projects. The reality is you can customize, but you shouldn't do it. Even if you do leave tracks of the NestJS railway, you will probably go back to the track for using some other functionality to work. Let me make it clear with a simple example:
You can opt out of the class-validator library in NestJS and use AJV for validation. It works without causing you problems but now you can't use automatic OpenAPI generation in NestJS.
Community and Documentation
Community and Documentation - FeathersJS
FeathersJS has a small, helpful, and welcoming community. You can join the community in Discord. One thing very noticeable on the FeathersJS website is the Ecosystem page where community-driven FeathersJS packages are promoted!
FeathersJS documentation walks you through everything you need in the framework. It is simple and clear. There are a few amounts of blog posts or online courses for FeathersJS, but I think numbers will go up after the latest release. David Luecke and other core maintainers are putting a lot of effort into the framework for some time, and I hope they get more recognition in the Node.js ecosystem.
Community and Documentation - NestJS
NestJS has a large, helpful, and welcoming community. You can join the community in Discord. NestJS has official online courses that can be purchased on its website.
I don't know how popular is their course but documentation on their website can get you through most of the things. To solve some problems you might need help from StackOverflow or GitHub issues but other than that, I think documentation and examples are enough. Can't skip here without mentioning NestJS Hero to Zero online course by Ariel Weinberger, which I've completed and found helpful.
I haven't had time to review the new Developer Tools by NestJS, but it looks like a very helpful tool. It is a paid tool by NestJS but at a low price. I think it would be much better if they released it for free at least initially.
Summary
You can build applications of any size and functionality whichever you choose. To choose between FeathersJS and NestJS means choosing between two different code styles. In my opinion, the development process in FeathersJS feels more fitting ( natural ) to the Node.js environment, but, I also understand the reason why NestJS is preferred by enterprise applications.
Mad respect to both David Luecke and Kamil Mysliwiec and all the other contributors, and maintainers of both projects for creating two of the strongest backend frameworks for Node.js.
If you have experience in either of the frameworks, I would like to know what you think, please share your experiences and opinions in the comment section.
I hope you learned something new, have a good one!
Top comments (2)
Been waiting for this one. Massive thanks from the feathersjs community for the comparison 👏
(Will share thoughts more after work)
Hi @nubuck, thanks for the kind comment 🙏