How to Build Node.js Applications with Fastify: Panoramic Guide

Personally, I got to know about Fastify as Matteo Collina would constantly tweet about it. This piqued my interest, and I was curious about how this framework works.

I have been a good user of Express before now. So when I came across Fastify, I asked myself, “So why should I use Fastify instead of the Express I was used to?”

So the first thing I did was to research how Fastify is better. After understanding the theoretical advantages, I also delved into how to use the Fastify framework in a real-time Node.js application.

As a developer, the framework's theory and practicality are important to my holistic understanding.

This is also why I created this content - to give other engineers a panoramic overview of what Fastify is about and how you can use it to build.

A Brief Note About Fastify

Today, top companies like Microsoft, Genesys, and Flux use Fastify in production. This shows that the framework has received a warm welcome among developers.

In fact, it is now a normal Node.js framework every developer is expected to use.

Matteo Collina and Tomas Della founded Fastify some years back to help backend developers build more scalable products. Here are a few notable things to note about the framework:


A more popular model of open-source frameworks is having a small team of about 4 people who would maintain the project, fix bugs, and ship releases.

This model is not often sustainable, bearing in mind that open-source is not paid, and maintainers will have to give attention to the company where they work.

Fastify embraces a community-driven approach to curb this and ensure long-term sustainability. Thus, anyone who wants to improve the framework has to raise a PR. At the moment, there are 15 active collaborators.

Plugin System

We all use several needed plugins while building backend applications. Fastify also supports a lot of plugins for better developer experience.

The ecosystem has two types of plugins: core and community. The former are the plugins the core team introduced and maintained; they are responsible for it.

On the other hand, the latter are the plugins the community members requested and took the responsibility to maintain. At the moment, there are a total of about 281 total plugins.

The ones that fascinate me are the MongoDB and Swagger plugins.


From the name, Fastify prioritizes speed. According to the benchmark data on its Website, while Fastify can process 45107 requests per second, a framework like Express can only do 10757 requests per second.

Generally, the closest framework to Fastify is Koa, which can process 35571 requests per second. At the moment, Fastify seems to be the fastest framework for Node.js.

Affordable Logging

Logging is important to keep track of important events. However, it can often increase the cost of running the project.

On this note, Fastify uses Pino, a special logging tool that drastically reduces logged events' costs.

Demo: Building a Node.js Application with Fastify

Now that you understand how Fastify works, a better way to cement your understanding is to build something with it in real time.

Subsequently, we will build a simple API to check some items. For this tutorial, I assume a basic understanding of Node.js as I would not over-explain.

A bit of disclaimer here: I gained 90% inspiration for this codebase from this YouTube tutorial I tried out myself.

First of all, run npm init -y to create a package.json for your project. Then install Fastify with npm install fastify. You should also install Nodemon locally with npm install -D nodemon for automatic server launching.

Step 1: Creating the Server

Create a file with the name “server.js”.

const fastify = require('fastify')({ logger: true})

const PORT = 3000

// you register routes in Fastify


// starting server asynchronously, while using try/catch for error handling

const start = async () => {


await fastify.listen(PORT)

} catch (error) {






Here, we created the server with port 3000, registered a route—which we will later define—and then started our server asynchronously.

Step 2: Creating Items File

Create a file and name it “Items.js”.

let items =  [

{id: '1', name: "John is a technical writer"},

{id: '2', name: "John is a backend developer"},

{id: '3', name: "John is a content strategist"}


module.exports = items

This acts more or less like our database. You can simply connect to your database, such as MongoDB, for production-level projects instead.

Step 3: Creating the Routes

Create a folder named “routes.” Under it, create a file called “items.js”.

const items = require('../Items')

const {getItems, getItem, addItem} = require('../controller/items')

const Item = {

type: 'object',

properties: {

id: {type: 'string'},

name: {type: 'string'}



// this fetches all the items

const getItemsOptions = {

schema: {

response: {

200: {

type: 'array',

items: Item,




handler: getItems,


// this fetches only a specified item

const getItemOptions = {

schema: {

response: {

200: Item,



handler: getItem,


// const postItemOptions = {

//     schema: {

//         response: {

//             201: Item,

//         }

//     },

//     handler: addItem,

// }

function itemRoutes(fastify, options, done) {

// items is an endpoint

// req & reply form the handler

fastify.get('/items', getItemsOptions)

fastify.get('/items/:id', getItemOptions)

//'/items', postItemOptions)



module.exports = itemRoutes

Create an itemRoutes function with three arguments: fastify, options, and done. Create two get requests within the function: one is for getting results about all the items, while the other one will be for a specific item.

If you notice, our get requests were not too verbose. That was because we cleaned up the code with schemas-based options.

Step 3: Creating the Handlers

Create a folder and name it “controller”, and create an “items.js” file under it. You should know how handlers work if you are familiar with the MVC architecture.

For those who don’t know, we wanted to clear up our code in the route, so we are creating controllers in a separate file.

This will keep the code readable and easy to maintain.

const items = require('../Items')

const getItems = (req, reply) => {



const getItem = (req, reply) => {

const { id } = req.params

const item = items.find((item) => ===id)



// const addItem = (req, reply) => {

//     const {name} = req.body

//     const item = {

//         id: uuidv4(),

//         name,

//     },

//     items = [...items, item]

//     reply.code(201).send(item)

// }

module.exports = {




Here, we created two handlers for each of our GET requests.

  • getItems is the handler for the multiple item request in the route

  • getItem is the handler for the single item request in the route

Step 4: Testing the API with The Rest Client

Rest Client is a good tool for testing APIs. You can also use the Postman VS Code Console if you prefer it.

Create a file and name it “client.http”. Past these HTTP localhost URLs:

GET http://localhost:3000/items HTTP/1.1

GET http://localhost:3000/items/3 HTTP/1.1

You should get this result:

HTTP/1.1 200 OK

content-type: application/json; charset=utf-8

content-length: 145

Date: Thu, 28 Dec 2023 18:49:43 GMT

Connection: close



"id": "1",

"name": "John is a technical writer"



"id": "2",

"name": "John is a backend developer"



"id": "3",

"name": "John is a content strategist"




HTTP/1.1 200 OK

content-type: application/json; charset=utf-8

content-length: 48

Date: Thu, 28 Dec 2023 18:50:46 GMT

Connection: close


"id": "3",

"name": "John is a content strategist"


Here is the full code. Congratulations, you just built your first application with Fastify!

Wrapping Up

This content is a panoramic guide to using Fastify, meaning the framework is bigger than this in terms of depth and building cutting-edge projects.

On this note, I recommend you read the official Fastify documentation.

I hope this piece has given you a panoramic idea of how the Fastify framework works. Kindly follow me on LinkedIn. Feel free to hit me up if you encounter any bugs in your code. Thanks for reading!