This article explains how we chose our NodeJS framework at Theodo. Among others, we focused on ExpressJS, KoaJS, NestJS, MeteorJS, and SailsJS.
So we started looking for a NodeJS framework that would empower us to write code that would be:
- 🔒 Secure: No need to say how important security is, I intentionally placed it first 🙂 Both the company operating the website and the end users must be protected.
- 🚀 Scalable: I am not so much talking here about scalability in terms of traffic, but rather speed of development of a feature on the very first day of the project or after 2 years of active development. It should be and remain straight-forward.
- ♻️ Maintainable: Zero bugs! And nearly impossible to introduce one.
I will now go deeper into our decision process.
Select front runners
We didn’t have the time nor the will to benchmark every single NodeJS framework out there, so we first decided to select 4-5 front-runners. For this, we picked the following:
- More than 10k 🌟 on Github
- Latest bug fix less than 1 month old, latest feature less than 3 months old
- Answer to issues in less than a day
- At least one major sponsor backing the NodeJS framework
Define decision criteria
One common pitfall is to consider right away the pros and cons of each solution. This leads to highly opinionated discussions, that can drift from the initial goal.
Take this statement for example: “NestJS is cool because it makes use of AngularJS CLI”. We don’t know if it is a good thing in regards to our target, and we cannot evaluate how other NodeJS frameworks compare.
This is why we first determined what would be our decision criteria.
|🔒 Security||Is there a security module available out of the box?|
|Does it handle access control by routes, roles, input validation?|
|🚀 Scalable||Is the developer guided in all of his architectural choices? Via injection dependency, for example, configuration files, etc.||The learning curve should be pretty smooth, and it should be near-to-impossible for a developer to do something the wrong way.|
|Is the documentation exhaustive, with code snippets?|
|Is there an available ORM ? Are there migrations? Is there normalization/serialization? How comprehensive are entities relationship?||We mostly use SQL databases (PostgreSQL) for the use cases we meet, so the thoroughness of the ORM is important to us.|
|♻️ Maintainable||Is the framework typed?||Since we have started using TypeScript, the developer experience has improved a lot: prevent bug, auto-imports, jump to definitions, etc. A natively typed framework is a plus.|
|Is the framework himself tested?||How easy is it to do unit testing, integration testing?|
|Are there development / debug tools?||We found out this depends more on the IDE than on the NodeJS Framework. VScode, for example, has amazing built-in debugging support.|
|Are there a lot of “magical methods”, indirection? Are such behaviours easily overridable if needed?||It might be great when prototyping a website, but when you want to have a robust production, not understanding what happens under the hood is a major drawback.|
|Is the framework decoupled from the ORM, the client?||Some projects start from scratch, others have a legacy. Sometimes we migrate part of an application. For these reasons we want all frameworks/libraries of our stack to be loosely coupled.|
|👪 Support||Is it widely adopted by the community? What is the trend like? How many 3rd party modules are there?|| Tools such as google trends can be useful here:
Github also provides a lot of interesting insights.
|How is the support for issues? Are there experts close by, in Paris? London? New York?||Our offices are in Paris, London and New York 🙂|
|Are Theodo developers enthusiastic about this framework?||It may sound trivial, but you cannot choose a framework if nobody in your company is willing to promote / work with it.|
These criteria are of course very opinionated. You’ll notice for example that I didn’t mention performance at all. This is because the number of rps (requests per second) a framework can handle has never been a blocking factor on any of our projects so far. Using Varnish cache or a CDN among other solutions has always proven itself to be enough.
On the other hand, you can discard some criterion, like the ORM if you don’t work with SQL databases.
We then gave a rating to each criterion, ranging between 0 and 3:
- oo : No support
- oo : Partial support
- oo : Extensive support
- oo : The best available
And here are the scores :
|Criteria||MeteorJS||NestJS||SailJS||KoaJS + middlewares||ExpressJS + middlewares|
|🚀 Architectural guidance|
|♻️ Debug tools|
|👪 Internal Enthusiasm|
The decision: which NodeJS framework we chose
MeteorJS was KO’d, because of the drawbacks that are inherent to its good qualities. Its all-in-one philosophy makes it possible to prototype an app very quickly. However our clients often already have an existing frontend or infrastructure, so Meteor was not what we were looking for.
ExpressJS and KoaJS
These 2 frameworks are very similar. We didn’t select them mainly because they provide too much freedom when designing the architecture and choosing the middlewares. Plus some of these middlewares seem to have less support and poorer documentation.
And the winner is…
We see on our benchmark that it scores more on most criteria than the last remaining contender SailJS. We were especially receptive to all the good design patterns and architectural stability it promotes, which makes it closer to Symfony or Django that we know quite well.
It relies on ExpressJS under the hood, so it basically includes all its features and is compatible with most of its middlewares. But it can be substituted with another library, in particular there is built-in support for Fastify if performance is a concern to you.
The fact that it is typed with Typescript has a lot of amazing consequences: enable database migrations and object validation based solely on the entity interface, ease code understanding, improve the developer experience, etc. This, as well as great integration with third-party libraries like Passport and Typeorm are the main reason NestJS scored high for many different criteria.
Its surging popularity is also spectacular, and the v6 release went live a few weeks ago with a bunch of amazing features.
Again, I can’t emphasize too much the fact that NestJS proved to be the best solution for us, but that doesn’t mean it is for you!
The nest step (next step, get it?) is to get better at NestJS. Indeed, working on the right framework is not enough if your teams can’t make the most of it! This is why we launched the NestJS Paris Meetup, to share with other aficionados insights and good practices about this framework. The CFP for the next event in Paris in May is opened (here) by the way 😉
I’d love to get your thoughts on this! How did you choose your NodeJS framework, what were your decision criteria?