Announcing Fastify v4 release candidate!

Fastify
4 min readApr 12, 2022

--

Photo courtesy of Sammy Wong @ Unsplash

We are excited to announce the first RC release of the fourth major version of Fastify! This release contains various improvements of the developer experience and very few breaking changes. We now support only Node.js v14+, and have fixed some bugs which required a breaking change, such as the new url parameter parsing, returning undefined from async functions and error handling. We are sure all those fixes will be appreciated and convince you to upgrade to the next major!

You can test it with:

Following a few highlights of the new features which we are most excited of:

Avoid the “resolved with undefined” problem once and for all

Since its inception, Fastify has combined a callback-based API (`reply.send({ hello: ‘world’ })`) with a promise-based one (`return { hello: ‘world’ }`). However this has caused a lot of confusion when mixing them, resulting in FST_ERR_PROMISE_NOT_FULFILLED being logged.. and most people did not know how to fix it. Since v4, we are making it mandatory to `return reply`. if you want to call reply.send after the route handler has completed its execution.

New error handling composition

This is one of the biggest improvements of this release. Prior to Fastify v4, the error handling was inconsistent, each custom error handler was on its own, and if it threw an error, the final response would have been different based on where in your code that error had been thrown. In Fastify v4, custom error handlers are encapsulated, and if a custom error handler throws inside a plugin, the parent one will catch that error and handle it. As a result, the errors that your application will send back will always be consistent.

New Pino Transports

Our out-of-the-box logger Pino, has been upgraded to v7, which means that from now on Pino transports will no longer need to live in a separate process, but can take advantage of worker threads! This will vastly improve developer experience and simplify configuration. Take a look at this blog post to know more.

Faster cold start

Fastify uses AJV under the hood for request validation and response serialization. The current bottleneck was the use of uri-js which was slowing down the cold start by its processing speed and its size. Fastify team developed a lighter alternative : https://github.com/fastify/fast-uri

By then the startup time had improved by 150%.

Reference:
https://github.com/ajv-validator/ajv/pull/1862

New Pino Types

Pino@7 ships with its own types! So you can now specify all the options for Pino straight from the Fastify factory, without installing any additional types.

Type providers out of the box

Type Providers are a TypeScript only feature that enables Fastify to statically infer type information directly from inline JSON Schema. They are an alternative to specifying generic arguments on routes; and can greatly reduce the need to keep associated types for each schema defined in your project.

Deprecation of variadic .listen signature

The improvements to developer experience are not limited to users of Fastify. With this release, we are starting to make the Fastify contributor experience better by simplifying code where possible. This effort begins with deprecating the variadic signature of the fastify.listen() method. Prior to this release, all of the following invocations of this method were valid:

  • fastify.listen(8000)
  • fastify.listen(8000, ‘127.0.0.1’)
  • fastify.listen(8000, ‘127.0.0.1’, 511)
  • fastify.listen(8000, (err) => { if (err) throw err })
  • fastify.listen({ port: 8000, host: ‘127.0.0.1’ }, (err) => { if (err) throw err })
  • And many other permutations

Starting with Fastify v4, the .listen method accepts an options object and an optional callback. Any other combination of arguments will result in a deprecation warning in v4. This will ultimately simplify the code that needs to be maintained within Fastify, making contributions like listening on both IPv4 and IPv6 at the same time easier to create. It should also result in easier to maintain TypeScript types, and, as a result, better Intellisense for the .listen method.

So, with Fastify v4, the following invocations are valid:

  • fastify.listen()
  • fastify.listen({ port: 8000 }) // returns a Promise
  • fastify.listen({ port: 8000 }, (err) => { if (err) throw err })

find-my-way v5

find-my-way is Fastify router. Its main feature is the use of a radix prefix trie to match a route: there where quite a few edge cases to handle to offer the same developer experience of the battle tested path-to-regexp. In v5, Ivan Timoshenko fixed quite a few of them:

Ajv v8

Fastify v4 includes Ajv v8, you can read how to migrate your schemas at https://ajv.js.org/v6-to-v8-migration.html

Drop support for old Node.js versions

As part of our Fastify v4 release, we are dropping support for Node.js v10 and v12, while v14, v16 and v18 will keep being support for this Fastify version.

Next steps

Now that the first RC is out we will be upgrading all of our core plugins to be ready for the next major version, and we highly encourage you to do the same if you are maintaining a community plugin! RC is already extremely close to the stable release, so you can upgrade already and provide feedback in our Discord channel or in the help repository.

You can see every other breaking change that we are shipping in Fastify v4 here.

Please let us know about any compatibility and upgrade issues at fastify/help!

Happy coding!

The Fastify Team

--

--