DEV Community

Cover image for Why should I prefer Fastify to Expressjs?
Manuel Spigolon
Manuel Spigolon

Posted on • Edited on

Why should I prefer Fastify to Expressjs?

"Why should I prefer Fastify to Expressjs?"

A lot of people ask me this question over and over again, so I would like to share why I prefer
Fastify to Expressjs because the correct answer to this question is just one:

You should prefer the framework that fit best your needs

Disclaimers:

  • I'm a happy Fastify maintainer, so that I could be a bit biased
  • I think expressjs is a great project and a pillar for the Node.js community, and the core team is doing a great job to push forward this framework
  • Opinions expressed are solely my own and do not express the views or opinions of the Fastify community
  • My knowledge is about expressjs@4.x

So...

Why I prefer Fastify to Express

I prefer Fastify to Express for the productivity.
That's all 😀

It seems simple, but this word means that Fastify ships with some key features necessary for me to be productive.

Async

Fastify supports async/await out of the box for all the components that must be awaited like:

  • route handlers
  • application hooks
  • server methods like .listen()
  • await plugins loading (like a mongo connection) before start listening

Doc Reference

JSON Input

By default, Fastify has a secure JSON body-parser to read the request body. You don't need anything else to accept application/json inputs.

Doc Reference

Tests

Fastify explains in its official documentation how to write the test for it!
Moreover, it is designed to run fast on test too, this is possible starting the server without listening to the host's PORT, so you may run in parallel tests to speed up the execution (again: using tap the parallel execution is the default behaviour!)

Actual use case: during my job, I migrated a codebase from expressjs@3 to fastify@2, and the test execution time has more than halved!

Doc Reference

Logging

Fastify has a logger included, so I don't have to think about how to log or store the logger instance and boring stuff like this.
Moreover, the default logger (aka pino) has so many plugins, so push the logs everywhere that it is impossible to lose them!

Doc Reference

Configuration

The application configuration is always a pain (usually), but with Fastify decorators or using its plugin system, getting the options is so simple:

// index.js
const myAppConfig = { awesome: true }
fastify.register(myAppPlugin, myAppConfig)

// my-plugin.js
module.exports = async function myAppPlugin (instance, opts) {
  console.log(opts) // print: { awesome: true }
}
Enter fullscreen mode Exit fullscreen mode

Doc Reference

JSON Schema

JSON Schema is another tool included in Fastify, so you don't need to struggle to configure it. You can use it.

Doc Reference

Plugin system

TLDR: Fastify runs the minimal amount of functions to process a request.

I need to make a comparison of the framework architecture here.

expressjs implements the middleware pattern: so the request is processed sequentially by a list of functions that are executed one by one.

fastify implements a tree data structure + the middleware pattern: the request is routed to the right branch to execute, and then it is processed sequentially by only the functions needed.

So, adding a middleware in expressjs will affect all the requests, even if not necessary.
In Fastify, instead, you can add a hook only to a limited set of routes or even on one route.
This kind of architecture will avoid introducing bugs on routes that should not be affected by new middlewares.

Doc Reference

Release schedule

Fastify has a clear Long Term Support (LTS) policy and
it is released whenever there is new bug fixes or new features.

For example, Node.js 16.10.0 introduced a new option to manage the maximum requests a socket can handle.
This option has been shipped in Fastify after 7 days by receiving a pull request.

The expressjs module has not a new release since 2 years ago (at the moment v4.17.1).
For sure you can set the new option in express too, but you will need to create the http server
by yourself, and you will need to use the http.Server class - but I think I'm using a framework
to avoid that.

Money

[Update 2022] I forgot to mention that a more efficient framework leads to lesser servers' resources. It means that to manage X req/sec you will pay less your cloud provider or you will be able to install more applications on the same server instance! I worked on a migration from .NET to Node.js/Fastify and we turned off ~10 AWS t4g.xlarge EC2 instances.

Monkey Patching

[Update 2023] Fastify has its own Request and Reply objects that are built on top of the Node.js's http.ClientRequest and http.ServerResponse. This is more flexible because Fastify does not break the Node.js internals, and both can evolve without conflicting with each other. Express, instead, monkey patch those standard objects with an impact on the Node.js contributors that must be caution to introduce new features because of Express!

Others

There are a lot more for me to prefer Fastify:

  • Fastify awesome community
  • the focus on performance

End

These are the main reasons why I prefer Fastify.
You should try it by yourself now and find your reasons! (if any, of course!)

For more Fastify content, follow me on Twitter!

Write comments here below or open an issue on GitHub for any questions or feedback!
Thank you for reading!

Acknowledgements

Image post credits to mohamed hassan (Creative Commons CC0)

Top comments (11)

Collapse
 
nirnejak profile image
Jitendra Nirnejak • Edited

I think the article provides a very good case for using Fastify over Express.js, lot of good points, If someone wants to get a bit more technical details and code example on the subject I would suggest reading this - Express.js vs Fastify - In-Depth Comparison of Node.js Frameworks

Collapse
 
eomm profile image
Manuel Spigolon

Nice article tho!

Collapse
 
annouar profile image
Annouar

Hey ! Thanks a lot for your feedback.

I personally would love to try Fastify and play with it. Honestly, I could even use it for my next production project (I am talking about pure Falsify, not Nest + Falsify).

Nevertheless, I regret the lack of serious starter or boilerplate for production-ready fastify project, as you can find on Nest, Koa, Express, ...

Collapse
 
eomm profile image
Manuel Spigolon

I agree on using pure Fastify: this avoids a lot of useless headache for what I saw on SO - a lot of unanswered questions.

I regret the lack of serious starter or boilerplate for production-ready fastify project

Spoiler: we are working on it!

Collapse
 
sgtino profile image
Stefano Giraldi

I regret the lack of serious starter or boilerplate for production-ready fastify project

Spoiler: we are working on it!

Great news!
I started a prototype project to build my code template for production-ready fastify project. It's available here (I will be honored to have some feedback) :-)

@eomm It's possible to follow the development of your project?

Thread Thread
 
eomm profile image
Manuel Spigolon

Not yet, but it will be possible in the near future 👍

Collapse
 
sarajohn130 profile image
sara john • Edited

All of your doc links are broken.

When you say "So, adding a middleware in expressjs will affect all the requests, even if not necessary.", you can add middleware just to specific routes: see "Router-level middleware" in the docs: expressjs.com/en/guide/using-middl...

Can you expand on the monkey patching part with specific examples?

Collapse
 
eomm profile image
Manuel Spigolon

Thanks, links fixed.

Can you expand on the monkey patching part with specific examples?

It is in the source code:

github.com/expressjs/express/blob/...

Here a better video: youtube.com/watch?v=imw7bIjODr0

Collapse
 
sarajohn130 profile image
sara john

Your first doc link is still broken: link

You should add that express source code link to the article.

And how is Fastify builidng on top of http.ClientRequest not monkey patching? Express builds on top of http.IncomingMessage, how is this monkey patching? Isn't building on top of something inherently monkey patching as changing that underlying thing will change everything on top of it?

Collapse
 
hello10000 profile image
a

how long have you been working as a dev, & how much do you need to know to be able to build a framework like this

Collapse
 
eomm profile image
Manuel Spigolon

I'm contributing to Fastify since 2019 and I think to build a framework like this one you need to know how Node.js works under the hook. There is a lot of prototype inheritance to implement the encapsulation system that is not trivial