12 October 2022
Fastify – let’s take a look at the super-fast web framework for Node.js
Web frameworks make building Node.js web applications easier. They take the guesswork out of handling requests and HTTP methods. They provide dynamic HTML rendering, templates, and architectural patterns that make developing apps easier. Over the years, Express became the Node.js web framework of choice. But is it always the best one? The creators of Fastify believe that it’s not the case. I was able to experience Fastify first-hand during a recent project. Do I side with them or not?
Just a while ago, my Node.js team and I worked on a project of a reward system for players of various free-to-play online games. The client wanted to revamp the whole app dramatically. For all intents and purposes, we were to develop a whole new version of the system.
One of the primary project requirements was increasing the speed of the system. The app had a lot of users who performed a lot of actions. The requests per second metric was of particular importance.
Our natural framework of choice for Node.js-based was Express. It’s easy to learn, very well documented, and highly flexible. But since speed was supposed to be such a big factor, we decided to take a closer look at other options in order to make a proper speed comparison.
Soon enough, we started considering a framework that bears a name that’s meant to make you instantly think of speed – Fastify.
What is Fastify?
Fastify is a Node.js library that was created by Matteo Collina and David Mark Clements in late 2016. The latest version out there is 4.7.0. If you are interested in the release history, check the information about long-term support and corresponding release notes.
Fastify was born out of a desire to create a general-purpose web framework that would provide a great developer experience without compromising on throughput and performance.
Fastify is downloaded more than 700,000 times a week. At this moment, it is used in about 25,000 projects. A lot of companies are already on board, including giants such as Microsoft. Here are some of the businesses that use Fastify.
Fastify performance – speed test
When the client expressed their interest in prioritizing application speed, we decided to try out Fastify. They say it is one of the fastest web frameworks. Naturally, we couldn’t pick it up on reputation alone.
We tried to find as many research sources on the topic of Fastify as possible. Then, we decided to run tests on our own.
To that end, we used the wg/wrk benchmarking tool. We compared Fastify and Express in 10 independent tests. We expected Fastify to be faster, but we needed detailed information to decide whether changing the Node.js framework is worth the trouble.
The comparison included a number of factors:
- requests per second,
- number of requests served in 30 seconds,
- transfer per second,
- average latency.
Here is our Fastify test data:
In every single test, Fastify proved superior. On average, the framework performed about 25 percent better than Express.
Our findings both surprised and impressed us. They influenced our decision to switch to Fastify. However, they were hardly the only factor.
In order to explain it fully, let’s take a closer look at the framework.
Why use Fastify?
Based on our observations, Fastify’s advantages can be grouped into four categories.
Performance
We already talked about speed. But Fastify is also highly scalable, making the framework suitable for both small and large projects. The JSON format automatically analyzes Fastifiy’s functions, ensuring fast routing of data packets across the network. That’s what makes the framework lightning-fast.
Maintainability
Fastify is a low overhead web framework, which minimizes maintenance costs for the entire application. In addition to that, it’s a web framework highly focused on security that guarantees a system of automatic security and data validation.
Flexibility
Fastify supports TypeScript, cooperates with AWS Lambda, and communicates with its API via a GraphQL adapter. As a result, it is great for web application development as well as API interface development.
Ease of development
One of Fastify’s biggest pros in serverless applications is the ease of development. In your local environment, you will always run the Fastify application directly, without the need for any additional tools, while the same code will be executed in your serverless platform of choice with an additional snippet of code.
Do you think that Fastify could be the technology for your next project?
Why don’t you contact us to consult it?
Do you want to efficiently handle your server’s resources while serving the highest number of requests possible? Do you want to do all that without sacrificing security validations and handy development?
Fastify was made for this scenario.
The project I mentioned before is a perfect example of such a scenario. The client expected the app to be used by an enormous number of people. And since we wanted the new version to be a definite upgrade of version one when it comes to performance, changing Express to Fastify was a logical step.
When not to use Fastify?
Naturally, everything has its pros and cons – Fastify is no exception. As of 2022, the framework is not widely used in the industry. It is being increasingly adopted, but its use is still modest when compared to Express or Nest.
In addition to that, being a fairly young project, the documentation is not as expansive as you might expect from more mature frameworks. The community support is so-so. If you plan on using a library such as passport.js, you will find that it doesn’t work with Fastify. Make sure that Fastify is compatible with all of the other pieces of software you want to use.
If you are an inexperienced developer looking for a job, you might find that very few employers are currently looking for devs that know Fastify specifically. Consequently, you might be better served going for something more mainstream.
However, if you already know Express, learning Fastify can give you additional options to use in your project and provide with you a different perspective on web development in Node.js. Its architecture really stands out and that alone makes it worth checking out. But more on that later.
Fastify practical tutorial
If you think that Fastify is something for you, stick around because we’re going to demonstrate how you can implement it so that it can support your own project.
Implementation
We’re going to make a simple Fastify project. The implementation of Fasitfy is quite similar to what you might have experienced with Express.js.
Let’s start with the implementation of basic modules: router, app, and server.
To do this, we’re going to recreate three files:
- server.js – the main script of the application,
- app.js – the script in which we create a Fastify Node server instance,
- router.js – Fastify router instance that helps us encapsulate routes and plugins.
We’re going to create a total of four ts files in the process: server.ts, app.ts, router.ts, and routing.ts.
For Server.ts, we simply use our createApp function from app.ts. We start by defining a port on which the server will be listening. The file also includes a simple example of how to use Fastify’s logger.
The app.ts file is the heart of our code. Here, we create the createApp function that initializes the Fastify instance. Here, we also register plugins via app.register (the example shown registers cors, helmet, and swagger). The router is also registered here.
The router.ts defines the way in which the client requests are handled by the application endpoints. The router gathers routings for all the features. In the example below, we register usersRouting in the router. We pass the router to app.js. That’s also where we register it.
There is also routing.ts. It handles routing for users. We use it to define every endpoint related to users. The example shows how you can define the get endpoint.
Fastify’s plugins
One of the most important changes Fastify brings is replacing middleware with plugins. Fastify really does have a powerful plugin architecture. What are those plugins?
A Fastify plugin can be a set of routes, a server decorator, or pretty much anything. Let’s say we need to send queries to the database from various application modules. Do we need to connect to the database, export the connection, and then import it into any modules we need to use it in? This works but results in spaghetti code.
This is where the Fastify plugin system shines the most. It allows us to inject our dependencies into a Fastify instance and then use them anywhere we have access to the instance. It also helps to easily move from a monolithic structure to microservices since each service can be a standalone plugin.
The Fastify ecosystem of plugins is ever-growing. There’s probably already a plugin for your favorite database or template language or even functionality.
Here are a couple of examples:
- cors -> Fastify-cors,
- helmet -> Fastify-helmet,
- express-jwt -> Fastify-jwt,
- multer -> Fastify-multer,
…. and many more!
Here is a full list of all core Fastify plugins.
Getting the most out of Fastify
Fastify also has a range of extra features that allow you to do even more.
Validation
Fastify uses Ajv under the hood, which allows you to define validation rules with JSON schema; Learn more about how validation works in Fastify.
Logging
Fastify uses a fast and flexible logger: pino. The logger instance is available on the Fastify server instance (such as Fastify.log.info(“…”)) and on all Request objects (such as request.log.info(“…”));
Logger usage is simple. You just need to enable it because it is disabled as default:
Then, you can use it like this:
Error handling
Fastify provides a setErrorHandler() method, which allows you to explicitly specify a function for error handling. For more, you can specify different Fastify error handlers using plugins.
Fastify tries to catch as many uncaught errors as it can without hindering performance. This includes:
- synchronous routes: app.get(‘/’, () => { throw new Error(‘kaboom’) })
- async routes: app.get(‘/’, async () => { throw new Error(‘kaboom’) })
Decorators
They allow us to customize core Fastify objects such as the server instance itself and any request and reply objects used during the HTTP request lifecycle. The decorators API can be used to attach any type of property to the core objects, e.g. functions, plain objects, or native types.
Fastify learning resources
Want to continue your research into Fastify? There are a lot of interesting resources out there that can help you out:
- Surely, you need to start with the official Fastify website, which has the docs, benchmarks, and more.
- The package manager for Node.js has a Fastify page with tons of useful information, including versions, dependencies, guides, and whatnot.
- The go-to place for the latest contributions to the Fastify framework codebase.
Migrating from Express to Fastify
- A very useful and practical article for everyone who wants to migrate from Express to Fastify in an existing project. It’s a highly recommended read.
Express vs Fastify performance comparison
- This article has a very interesting selection of performance data for Express and Fastify.
Fastify and web development trends
Fastify is constantly evolving. The Fastify framework is written in vanilla JavaScript, and as such type definitions are not as easy to maintain; however, since version 2 and beyond, maintainers and contributors have put in a great effort to improve the types.
Fastify type system
The type system was changed in Fastify version 3. The new type system introduces generic constraining and defaulting, plus a new way to define schema types such as a request body, query string, and more!
As the team works on improving framework and type definition synergy, sometimes parts of the API will not be typed or may be typed incorrectly. That’s why it is greatly compatible with Typescript.
Fastify – conclusions & lessons learned
Considering just how much developers love Express, one might ask – do we really need yet another web framework for Node.js?
My personal opinion is a resounding: YES. Healthy competition always spurs growth, leading to a never-ending drive towards faster, better, and more efficient solutions.
Fastify certainly has the makings of a great framework. I already consider it to be a great choice for both web development and API development, for a number of reasons:
- It’s fast, economical, and supports TypeScript out-of-the-box. The latter is a big bonus for large commercial projects.
- It works great with a variety of innovative technologies common in modern-day web development, such as AWS Lambda, or GraphQL.
- It plays to its strengths, specializing in handling the resources of your server efficiently and fast
However, good old Express is still here and is something we all can rely on. At the end of the day, there’s no good reason to permanently limit yourself to one framework, and shun all the newcomers. On the other hand, you shouldn’t suddenly go into a frenzy of refactoring every web application to Fastify either.
In the near future, it is safe to say that Fastify will not overtake Express in terms of popularity (Express with its 25 million downloads is enormous), but I think that it will certainly grow, and unless some new “competitor” is found, it may one day become as popular as Express. It certainly feels like it has all it takes.
I hope that by the time you start your next Node.js project, you’ll have done enough research into Fastify to make an informed choice on whether it is a good fit for the occasion!
Node.js is a key technology in the development of microservices
Learn more about the latest microservices trends from the State of Microservices report