Matteo Collina Matteo has many years’ experience in the software industry and is a well-known figure in the global Node.js, Internet of Things and open source software communities. He first started working with Node.js in 2010, and, to date, has released dozens of Node.js modules. He is also co-author of the book JavaScript: Best Practices (FAG Milan, 2013) .

The following is a contributed article from Node.js core technical committee member Matteo Collina, summarizing the talk he will give at the Node.js Interactive conference, to be held Oct. 4 – 6 in Vancouver.

Why have we written yet another web framework for Node.js? I am committed to making the Node.js platform faster, more stable and more scalable. In 2016, myself and David Mark Clements started Pino, which was designed to be the fastest logger for Node.js, and it now has four active maintainers and an ecosystem of hundreds of modules.

Fastify is a new web framework inspired by Hapi, Restify and Express. Fastify is built as a general-purpose web framework, but it shines when building extremely fast HTTP APIs that use JSON as the data format. These are extremely common in both web and mobile software architectures, so Fastify could improve the throughput of the majority of applications.

This is an example web server that renders a JSON response:

'use strict' const fastify = require('fastify')() fastify.get('/', function (req, reply) { reply.send({ hello: 'world' }) }) fastify.listen(3000) 1 2 3 4 5 6 7 8 9 'use strict' const fastify = require ( 'fastify' ) ( ) fastify . get ( '/' , function ( req , reply ) { reply . send ( { hello : 'world' } ) } ) fastify . listen ( 3000 )

Here is our Getting Started guide if you want to test it out now. For those that want a bit more of an explanation behind the why and the what of Fastify, please read on.

Reducing the Overhead

The above diagram shows the number of request/second to send a { “hello”: “world” } response as JSON. We use this simplistic benchmark to evaluate the overhead of all the various frameworks – it does not represent the actual throughput of a real-world application. We assert that Fastify is the framework with the lowest overhead compared to the feature that it provides.

Fastify uses fast-json-stringify to double the throughput of the rendering of JSON, and find-my-way to reduce the routing by a factor of 10 compared to alternatives. Fastify consumes the same middlewares that Express consumes, but we contend it is faster.

A good chunk of the speed increase in Fastify comes from the findings described in my “Reaching Ludicrous Speed” talk at Node.js Interactive 2015:

Fully encapsulated plug-ins

Fastify offers a plug-in model similar to that of Hapi. It adds full encapsulation of plug-ins so that each plug-in can use its own dependencies and hooks if it wants to. This enables greater software reuse and decoupling. Furthermore, the plug-in model is based on reentrant locks and graph-based, it perfectly handles asynchronous code and it guarantees the load order and the close order of the plug-ins.

Fastify has a wide range of plug-ins already developed, including those for template rendering, React integration, GraphQL support, serving static files, and database drivers.

The following server makes uses of this capability:

'use strict' const server = require('fastify')() server.register(require('fastify-helmet')) server.register(require('point-of-view'), { engine: { marko: require('marko') } }) server.register(require('./subsystem'), { prefix: '/subsystem' }) server.get('/json', (req, reply) => { reply.send({ hello: 'world' }) }) server.get('/', (req, reply) => { reply.view('/index.marko', { hello: 'world' }) }) server.listen(3000) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 'use strict' const server = require ( 'fastify' ) ( ) server . register ( require ( 'fastify-helmet' ) ) server . register ( require ( 'point-of-view' ) , { engine : { marko : require ( 'marko' ) } } ) server . register ( require ( './subsystem' ) , { prefix : '/subsystem' } ) server . get ( '/json' , ( req , reply ) =& gt ; { reply . send ( { hello : 'world' } ) } ) server . get ( '/' , ( req , reply ) =& gt ; { reply . view ( '/index.marko' , { hello : 'world' } ) } ) server . listen ( 3000 )

And subsystem/index.js:

module.exports = function (server, opts, cb) { server.register(require('point-of-view'), { engine: { marko: require('marko') }, templates: __dirname }) server.get('/hello', (req, reply) => { reply.view('/page.marko', { hello: 'world' }) }) cb() } 1 2 3 4 5 6 7 8 9 10 11 12 13 14 module . exports = function ( server , opts , cb ) { server . register ( require ( 'point-of-view' ) , { engine : { marko : require ( 'marko' ) } , templates : _ _ dirname } ) server . get ( '/hello' , ( req , reply ) =& gt ; { reply . view ( '/page.marko' , { hello : 'world' } ) } ) cb ( ) }

Note that both the “subsystem” plug-in and the main file register “point-of-view” provides handling of multiple templating languages. Those two instances of the plug-in are completely encapsulated via the use of prototypical inheritance, which makes it close to a zero cost abstraction. A similar approach with Express would cause the performance to drop significantly for each nesting level.

Check out our guide to know more about plug-ins.

Note: In the example, the Marko templates have been omitted, you can check the full source code on GitHub.

Made in Italy with Love

Fastify is currently sponsored by nearForm and LetzDoIt, which offers a new activities app and has just deployed Fastify to production. Fastify is fully made in Italy, between Udine and Forlì, where co-creator LetzDoIt engineer Tomas Della Vedova and myself live, respectively. We wrote it because we saw that the APIs for most web frameworks could not be easily optimized, and it would not reasonable to break backward compatibility.

I will present Fastify during my “Take your HTTP server to Ludicrous Speed” session at Node.js Interactive. I will also be holding a performance workshop alongside my colleague, David Mark Clements.

The Linux Foundation is a sponsor of The New Stack.

Feature image via Pixabay.