Skip to main content
All Posts By

OpenJS Foundation

Jest Project Moves to OpenJS Foundation with Meta Open Source Contribution

By Announcement, Blog, Jest

The OpenJS Foundation is announcing that popular JavaScript testing framework Jest is joining as an Impact Project! Jest and its assets are being donated proudly by Meta Open Source.

Jest is a JavaScript testing framework. It allows you to write tests with an API with little configuration. As the Jest team likes to say, Jest makes testing “delightful.”

Jest currently has over 17 million weekly downloads and 38,000+ GitHub stars, making it the most used testing framework in the JavaScript ecosystem. It consistently ranks as one of the JavaScript libraries with the highest satisfaction, and is used by companies of all sizes including Amazon, Google, Meta, Microsoft, and Stripe. Jest 28 was just released.

“We are excited to welcome Jest into the OpenJS Foundation. Building a community requires dedicated people and great technology, which Jest has been doing since 2011. Jest is used commonly in enterprise production environments and open source projects and will benefit from a reliable structure for open governance and legal support,” said Robin Ginn, OpenJS Foundation executive director. “As the vendor-neutral home to almost 40 open source projects, Jest already fits in well with our ecosystem of projects. We look forward to providing resources and support to Jest to help their community to grow.”

“Jest has been working to follow the OpenJS Foundation principles around operating transparently, openly, and collaboratively. Joining the OpenJS Foundation allows our team to make greater investments to grow contributors and impact,” said Rick Hanlon, Front End Engineer on React Core at Meta and Jest Core Contributor. “This is a big step forward for Jest. I want to thank the sponsors and contributors who have helped get us this far and who will continue to play an important role in Jest’s next stage.”

“We have been a community-led project for quite some time. We believe in community-led development, and continually strengthening our community, and joining the OpenJS Foundation will help us strengthen and broaden our community,” said Simen Bekkhus, developer at Folio and Jest lead maintainer. “I see this as a very positive change and a way for the Jest community to flourish.”

“Big thanks to Meta Open Source. JavaScript developers worldwide will benefit from having Jest be part of the OpenJS Foundation. This move strengthens the JavaScript ecosystem and will help the Jest developer community to continue to grow,” said Joe Sepi, OpenJS Foundation Cross Project Council chairperson and Open Tech Program Director at IBM. “Congratulations to the whole Jest team and community.”

“By moving to the OpenJS Foundation, we are becoming more open and welcoming to first-time community members and contributors. Open governance is key to the next step in our evolution as a community,” said Christian Bromann, OpenJS Foundation Cross Project Council Member representing the WebdriverIO project and Founding Engineer, Stateful, Inc. “I personally have learned you can earn a living by following your passion in life. We are making Jest a more inclusive community because we believe this is the best way to build a strong, vibrant community that will allow you to follow your passion.”

Just like all OpenJS projects, Jest is entering the foundation as an incubating project while they complete the on-boarding checklist process. Projects in this phase can be designated as an At-Large or Impact Stage project.

There are four different types of projects hosted by the OpenJS Foundation: Impact projects are generally large, mature projects. At-Large projects are new, stable projects with minimal needs. Incubation projects are in the process of joining the OpenJS Foundation. And Emeritus projects have completed their lifecycle and are retired. In addition, the CPC oversees an Incubation process for projects which seek to be hosted by the OpenJS Foundation.

To find out how your project can join the OpenJS Foundation see: 

Jest Resources

OpenJS Resources

Click here to learn more about how you could be a part of the OpenJS Foundation, and view these additional resources:

About OpenJS Foundation

The OpenJS Foundation is committed to supporting the healthy growth of the JavaScript ecosystem and web technologies by providing a neutral organization to host and sustain projects and collaboratively fund activities for the benefit of the community at large. The OpenJS Foundation is currently home to 39 open source JavaScript projects, including Appium, Dojo, Electron, jQuery, Node.js, and webpack. It is supported by 30 corporate and end-user members, including GoDaddy, Google, IBM, Intel, Joyent, Microsoft, and Netflix. These members recognize the interconnected nature of the JavaScript ecosystem and the importance of providing a central home for projects which represent significant shared value. 

About Linux Foundation

Founded in 2000, the Linux Foundation is supported by more than 1000 members and is the world’s leading home for collaboration on open source software, open standards, and open hardware. Linux Foundation projects like Linux, Kubernetes, Node.js, and more are considered critical to developing the world’s most important infrastructure. Its development methodology leverages established best practices and addresses the needs of contributors, users, and solution providers to create sustainable models for open collaboration. For more information, please visit their website.

About Meta Open Source

Jest is one of over 800 active projects from Meta within the worldwide open source community. Meta has long been a supporter of open source software and the open source community. In addition to making a lot of its engineering work publicly available including sharing research, code, designs, and engineering work, Meta also invest in organizations that are important for the long-term sustainability of the open source ecosystem. To learn more about Meta’s open source efforts, please visit Meta Open Source

Using AbortSignal in Node.js

By Blog, Node.js, tutorial

By: James Snell, originally published on Nearform July 22, 2021

Foreword by: David Mark Clements

Dave Clements is an open source advocate and is the tech lead and primary author of OpenJS Foundation Node.js training and certification programs. And a big thank you to Nearform and James Snell for allowing the OpenJS Foundation to repost this article.


The OpenJS Node Application Developer certification is an evergreen program that stays up to date
with advancements in the JavaScript specification, Node.js core, industry trends, and best practices
not only to ensure that the examination and training stay relevant but also to help disseminate
important information for the Node & JavaScript community.

With that in mind, the following article by James Snell is republished with permission from
James and NearForm where the article was first published. We strongly recommend anyone thinking
of taking the JSNAD certification read this article and consider the implications. We hope you
enjoy it!

The AbortController and AbortSignal APIs are quickly becoming the standard mechanism for canceling asynchronous operations in the Node.js core API.

If you search how to use the Promise.race() API, you’ll come across quite a few variations of the following:

The intent here is straightforward: Start a potentially long-running task but trigger a timeout if that task takes too long to complete. This is generally a good idea, but there are quite a few problems with this common example.

First, although the promise returned by Promise.race() will be fulfilled as soon as the first of the given promises is settled, the other promises are not cancelled and will keep on running. Although the timeout timer did fire, the long-running task is never actually interrupted and stopped.

Second, what happens to the timeout promise if the long-running task completes before the timeout is triggered? The answer is simple: The timer keeps running, and the promise will end up rejecting, still with an unhandled rejection — unnecessarily risking performance issues and possible memory leaks in your application.

To correctly handle this pattern, we need a reliable mechanism for signalling across the two promises, canceling either the timer or the long-running task as appropriate and ensuring that once the timeout is triggered all resources are cleaned up as quickly as possible. Fortunately, Web Platform APIs provide a standard mechanism for this kind of signalling — the AbortController and AbortSignal APIs.

In Node.js, a better way if implementing a Promise.race-based timeout would be:

As with the previous example, two promises are created. However, when each completes, it uses the AbortController and AbortSignal APIs to explicitly signal to the other that it should stop. As long as the code in those is written to support the AbortSignal API, everything just works.

For instance, in the example we make use of the recently added awaitable timers API in Node.js. These are variants of the setTimeout() and setInterval() that return promises.

The awaitable timer API supports the ability to pass in an AbortSignal instance. When the AbortSignal is triggered, the timer is cleared and the promise immediately rejects with an AbortError.

Support for AbortController and AbortSignal is being rolled out across the Node.js core API and can now be found in most of the major subsystems. Before we explore where the API can be used, let’s find out a bit more about the API itself.

All about AbortController and AbortSignal

The AbortController interface is simple. It exposes just two important things — a signal property whose value is an AbortSignal and an abort() method that triggers that AbortSignal.

The AbortSignal itself is really nothing more than an EventTarget with a single type of event that it emits — the ‘abort’ event. One additional boolean aborted property is true if the AbortSignal has already been triggered:

The AbortSignal can only be triggered once.

Notice that when I added the event listener in the example above, I included the { once: true } option. This ensures that the event listener is removed from the AbortSignal as soon as the abort event is triggered, preventing a possible memory leak.

Note that it’s even possible to pass an AbortSignal onto the addEventListener() itself, causing the event listener to be removed if that AbortSignal is triggered.

This starts to get a bit complicated too, but it’s important for preventing memory leaks when coordinating the cancellation of multiple complex tasks. We’ll see an example of how this all comes together next.

Implementing API support for AbortSignal

The AbortController API is used to signal that an operation should be cancelled. The AbortSignal API is used to receive notification of those signals. They always come in pairs.

The idiomatic way of enabling a function (like the someLongRunningTask() function in our examples above) to support this pattern is to pass a reference to the AbortSignal in as part of an options object:

Within this function, you should immediately check to see if the signal has already been triggered and, if it has, immediately abort the operation.

Next, it’s important to set up the handling of the ‘abort’ event before starting to process the task:

Notice here that we are creating an additional AbortController instance whose signal is passed in with the event listener. After we’ve completed the asynchronous task, we trigger that AbortController to let the AbortSignal know that the event handler can be removed. We want to make sure that the listener is cleaned up even if the async task fails, so we wrap the call to taskDone.abort() in a finally block.

It is also important to check if the signal has been triggered between various async tasks the method may be performing. This is important to catch cases where the event may not yet have had an opportunity to be emitted but the operation should still be interrupted.

Using AbortController and AbortSignal

The AbortController and AbortSignal APIs are quickly becoming the standard mechanism for canceling asynchronous operations in the Node.js core API.
For example, as of node.js 15.3.0, it is possible to cancel an HTTP request using the API:

Consult the Node.js documentation for more details on exactly which APIs support AbortSignal. More are being added all the time and support may vary across different Node.js major versions.

Node.js Framework LoopBack Graduates to At-Large Project at OpenJS Foundation

By Blog, Project Update

LoopBack fans will be happy to hear that the project has graduated from the Incubation stage at OpenJS Foundation! 

LoopBack is a popular Node.js framework for API creation and a platform to build large-scale Node.js applications. It uses proven patterns with TypeScript and gives support for SOAP and enterprise databases. It is a flexible developer-centric middleware that is being used in industries such as finance and insurance. 

Graduating is an important milestone that helps solidify LoopBack’s position as a vendor-neutral, community-driven open-source project. In June 2021, StrongLoop, an IBM company, contributed LoopBack to the OpenJS Foundation with the goal of growing the community’s active core of developers. Graduating to At-Large stage is a major step forward! They now have maintainers and Technical Steering Committee (TSC) members from different organizations worldwide. 

“We’re thrilled to have LoopBack as part of the OpenJS Foundation family of JavaScript projects. LoopBack is a great example of how open source communities flourish over time with open governance and sustained structural support,” said Robin Ginn, OpenJS Foundation executive director. “Congratulations to all the LoopBack contributors.”

LoopBack is one of 40 projects officially hosted under the OpenJS umbrella–joining platinum members Google, IBM, Joyent, and Microsoft.

“We’re excited that LoopBack has graduated from incubation and is officially joining the OpenJS Foundation’s hosted projects. Over the years, we’ve been moving towards a more open governance model–from actively recruiting maintainers outside of IBM to establishing a Technical Steering Committee made up of maintainers from different professional backgrounds. So joining the OpenJS Foundation is definitely a major milestone for LoopBack,” said Diana Lau, a maintainer and TSC member who has worked on the project since it was with IBM and is currently the senior development manager for API Connect Cloud at IBM.

Lead maintainer and TSC member Rifa Achrinza commented, “I’ve been heartened by the many contributions and support driven by the LoopBack community through channels such as GitHub and our ever-growing Slack channels. This steady community growth shows an increasing desire for a stable framework like LoopBack in the Node.js ecosystem.”

The project has also been working to develop open governance in line with OpenJS Foundation standards and with LoopBack’s new distributed maintenance model.
Project TSC member and maintainer Raymond Feng added, “The project has become much more community-driven under the OpenJS Foundation. I’m very happy to see LoopBack graduating from the incubation. It’s a great validation that LoopBack can be further maintained and developed by the community with a diverse pool of maintainers and contributors.” Raymond Feng was a co-creator of LoopBack and is currently Co-Founder and CTO of Abridged, Inc.

OpenJS Foundation’s Node.js CPC chairperson and voting member Joe Sepi Crane-Messina commented, “I joined IBM through StrongLoop and spent years working on and advocating for LoopBack. I couldn’t be happier to see it move into the foundation where it can grow and flourish.”

Recent LoopBack activity stats show that adoption in the community is growing. LoopBack has reached 4.1k GitHub stars and close to 216,000 npm downloads. Their Slack community has grown over 40% since incubating with the OpenJS Foundation and now has 1300 members. Additionally, LoopBack’s growth has been documented through quite a few user testimonials.

In the fast-paced Node.js ecosystem, the stability of LoopBack and the Juggler ORM has proven invaluable to those who demand a stable, complete solution while benefiting from the flexibility and simplicity of JavaScript.

The project has a few near-term goals. First, they have consolidated their blog and documentation site into the LoopBack website, where they plan to highlight the project’s maintainers and the journey to adopt LoopBack in their day job. In addition, they have planned security-related work including adopting OpenSSF Best Practices, publishing advisories in machine-consumable formats, and enhancing the vulnerability disclosure program. These goals aim to open new ways to interact with the community and strengthen LoopBack’s development focus on security.

This graduation signals a new major milestone for the framework as we continue to support the future of LoopBack in the ever-growing Node.js ecosystem. The OpenJS Foundation is proud to welcome them!

Node.js 18 Released With Improved Security, Fetch API, and Next-10 Strategic Initiatives

By Blog, Node.js, Project Update

Node.js 18 is available now! It adds multiple key features of enterprise and small- to medium-sized enterprises including increased security support, the Fetch API, and it is part of delivering on the larger Next-10 strategic initiative within Node.js that is pushing forward key priorities including modernizing HTTP and keeping Node.js on the forefront of web development. 

As part of increased security support, Node.js has been announced as the first pilot open source community to be supported by OpenSSF’s Alpha-Omega Project. Alpha-Omega is committing $300k to bolster the Node.js security team and vulnerability remediation efforts through the rest of 2022, with a focus on supporting better open source security standards and practices.

“The Node.js team continues to do fantastic work. The open governance structure for Node.js has led to tangible improvements in security and forward-thinking planning, and the main features of Node.js 18 will be highly valuable to enterprises of all sizes,” said Robin Ginn, OpenJS Foundation executive director. “Whether you’re a new user or already have Node.js broadly implemented, now’s a good time to install and test Node.js 18.”

Following its long-established release schedule, Node.js 18 is a Current release, which means it’s the right time for testing by enterprises, before being suitable for production usage when it is promoted to long-term support (LTS) in October 2022.

“The Node.js project contributors and collaborators continue to do an excellent job, and I want to thank them all. We continue to improve and grow, and I believe Node.js is a real open source success story,” said Bethany Griggs, Node.js Technical Steering Committee member, and Senior Software Engineer at Red Hat. “As always, current releases, like Node.js 18, are the perfect time to test in your own unique development environment. If you’re a Node.js user, please try out Node.js 18 and give us feedback. Your feedback directly contributes to our ability to move new features into stable releases more quickly.” 

For comprehensive information on specific Node.js features, see the Node.js team release announcement written by the Node.js project contributors: LINK

There are three key reasons to evaluate and upgrade to Node.js 18: Security, APIs, Future Planning.


This is the first version that will be later promoted to LTS with OpenSSL 3.0. OpenSSL 3.0 is a major new stable version of the popular and widely used cryptography library. OpenSSL contains an open-source implementation of the SSL and TLS protocols, which provide the ability to secure communications across networks. Among other key features, OpenSSL 3.0 contains a FIPS Module that has been submitted for validation. The Federal Information Processing Standards (FIPS) are a set of requirements enforced by the US government which govern cryptographic usage in the public sector. This is a key step forward in the cryptographic support in Node.js.

The Node.js project follows a well planned security release process, with regular outbound communications and more. In the last year, Node.js has formalized rotations around security. The commitment to take slots in the security release steward rotation is made by companies in order to ensure individuals who act as security stewards have the support and recognition from their employer to be able to prioritize security releases. 


Node.js 18 is adding even tighter synergy between front-end and back-end APIs. One of the key premises of Node.js is that JavaScript skills can be applied to the back-end. With Node.js 18, Fetch is globally available by default. The Fetch API provides an interface for fetching resources including across networks. It will seem familiar to anyone who has used XMLHttpRequest, but the new API provides a more powerful and flexible feature set.

“Node.js 18 will enable the Fetch API as a default. It’s been available since Node.js 17, but this moves forward Node.js application development, and it’s exciting to be a part of the process of improving Node.js in key fundamental areas,” said Michaël Zasso, Scientific research software engineer and co-founder at Zakodium, member of the Node.js Technical Steering Committee. “I would like to thank multiple team members and contributors, and in particular I would like to thank users who push us and support us. Thank you!”

XMLHttpRequest has been used by web developers enabling ajax and a whole new kind of interactive exposure. However, it has been slowly succeeded by Fetch API. Fetch API is Promise based, providing a cleaner and more concise syntax.

Future Planning

The Next-10 effort has elevated technical priorities which have led to discussions around modernizing http. The purpose of the Next-10 project is to work collaboratively on the strategic directions for the next 10 years of Node.js. Fetch API is one direct result of this process. The full Next-10 repository is available here: 

Node.js Training and Certification

The OpenJS Node.js Services Developer (JSNSD) and OpenJS Node.js Application Developer (JSNAD) certifications are available now. Node.js training courses are available to help you prepare for the exams: Node.js Application Development (LFW211) and the Node.js Services Development (LFW212). Discounts are available to members!

OpenJS Resources

Click here to learn more about how you could be a part of the OpenJS Foundation, and view these additional resources:

About OpenJS Foundation

The OpenJS Foundation is committed to supporting the healthy growth of the JavaScript ecosystem and web technologies by providing a neutral organization to host and sustain projects and collaboratively fund activities for the benefit of the community at large. The OpenJS Foundation is currently home to 39 open source JavaScript projects, including Appium, Dojo, Electron, jQuery, Node.js, and webpack. It is supported by 30 corporate and end-user members, including GoDaddy, Google, IBM, Intel, Joyent, Microsoft, and Netflix. These members recognize the interconnected nature of the JavaScript ecosystem and the importance of providing a central home for projects which represent significant shared value. 

About Linux Foundation
Founded in 2000, the Linux Foundation is supported by more than 1000 members and is the world’s leading home for collaboration on open source software, open standards, and open hardware. Linux Foundation projects like Linux, Kubernetes, Node.js, and more are considered critical to developing the world’s most important infrastructure. Its development methodology leverages established best practices and addresses the needs of contributors, users, and solution providers to create sustainable models for open collaboration. For more information, please visit their website.

Insights from the 2022 Fastify Survey

By Blog, Fastify, Project Updates

Survey finds web framework for Node.js is fast and performant

After the challenges that so many have faced the last few years, we really appreciate that so many Fastify users found the time to complete this survey. Fastify is a web framework for Node.js to help increase web performance, and is hosted by the OpenJS Foundation. Our community is everything, and getting feedback like this helps us to maintain and improve Fastify.

We had 108 respondents participate in this year’s survey, and surprising to no one,  the majority work in software or development, or are studying in those areas.

Most respondents found Fastify through GitHub, where Fastify’s repos reside. It is encouraging to see that Fastify is also being discovered through other mediums, which indicates a growing awareness of Fastify that will hopefully lead to more adoption and activity around the framework!

Where Fastify Excels

As the name of the framework implies, Fastify is fast and performant. Respondents overwhelmingly cited this as the reason why they enjoy using Fastify in their projects. Other positives included:

  • Active development and community
  • Documentation
  • Ease-of-use and simplicity
  • Growing plugin ecosystem
  • Support for modern JavaScript features
  • TypeScript support
  • Matteo Collina’s involvement as lead maintainer

These helpful features and benefits have been the result of years of work by maintainers and contributors alike, so we’d like to extend a big thank you to everyone who has been involved with Fastify! Also, thanks to Matteo Collina (Twitter: @matteocollina) for being so charming that he brings all the users to the yard.

Respondents also indicated a high level of satisfaction with Fastify across the board:

Where Fastify Can Improve

We know that “perfection isn’t attainable but if we pursue it we can attain excellence.”  So we asked what improvements users would like to see in future releases.

Requests for additional TypeScript support far outweighed any other, with requests for more examples and clarity in documentation ranking second in priority. 75% of respondents stated they use TypeScript, so this is not surprising!

V4 of Fastify resolves some of these grievances, with new automatic types for query strings and bodies, fixes for missing types, typed decorators, and more. One of the responses requested support for hot reloading, which is currently being explored through tooling like restartable!

The overall sentiment of this feedback has been positive. As Fastify progresses into V4 and beyond we hope that we can remove pain points in Fastify that users have highlighted in their responses, whilst continuing to provide the high-performance users have come to expect!

Many thanks to Alix Robinson and Matteo Collina for preparing the survey. This article was brought to you by Frazer Smith.

OpenJS In Action: How Wix Applied Multi-threading to Node.js and Cut Thousands of SSR Pods and Money

By Blog, Case Study, OpenJS In Action
Author: Guy Treger, Sr. Software Engineer, Viewer-Server team, Wix


In Wix, as part of our sites’ Server-Side-Rendering architecture, we build and maintain the heavily used Server-Side-Rendering-Execution platform (aka SSRE). 

SSRE is a Node.js based multipurpose code execution platform, that’s used for executing React.js code written by front-end developers all across the company. Most often, these pieces of JS code perform CPU-intensive operations that simulate activities related to site rendering in the browser.


SSRE has reached a total traffic of about 1 million RPM, requiring at times largely more than accepted  production Kubernetes pods to serve it properly. 

This made us face an inherent painful mismatch:
On one side, the nature of Node.js – an environment best-suited for running I/O-bound operations on its single-threaded event loop. On the other, the extremely high traffic of CPU oriented tasks that we had to handle as part rendering sites on the server.

The naive solution we started with clearly proved inefficient, causing some ever growing pains in Wix’s server and infrastructure, such as having to manage tens of thousands of production kubernetes pods.


We had to change something. The way things were, all of our heavy CPU work was done by a single thread in Node.js. The straightforward thing that comes to mind is: offload the work to other compute units (processes/threads) that can run parallely on hardware that includes multiple CPU cores.

Node.js already offers multi-processing capabilities, but for our needs this was an overkill. We needed a lighter solution that would introduce less overhead, both in terms of resources required and in overall maintenance and orchestration.

Only recently, Node.js has introduced what it calls worker-threads. This feature has become Stable in the v14 (LTS) released in Oct 2020.

From the Node.js Worker-Threads documentation:

The worker_threads module enables the use of threads that execute JavaScript in parallel. To access it:

const worker = require(‘worker_threads’);

Workers (threads) are useful for performing CPU-intensive JavaScript operations. They do not help much with I/O-intensive work. The Node.js built-in asynchronous I/O operations are more efficient than Workers can be.

Unlike child_process or cluster, worker_threads can share memory.

So Node.js offers a native support for threading that we could use, but since it’s a pretty new thing around, it still lacks a bit in maturity and is not super smooth to use in your production-grade code of a critical application.

What we were mainly missing was:

  1. Task-pool capabilities
    What Node.js offers?
    One can manually spawn some Worker threads and maintain their lifecycle themselves. E.g.:
const { Worker } = require(“worker_threads”);

//Create a new worker
const worker = new Worker(“./worker.js”, {workerData: {….}});

worker.on(“exit”, exitCode => {

We were reluctant to spawn our Workers manually, make sure there’s enough of them at every given time, re-create them when they die, implement different timeouts around their usage and more stuff that’s generally available for a multithreaded application.

  1. RPC-like inter-thread communication
    What Node.js offers?
    Out-of-the-box, threads can communicate between themselves (e.g. the main thread and its spawned workers) using an async messaging technique:
// Send a message to the worker
aWorker.postMessage({ someData: data })

// Listen for a message from the worker
aWorker.once(“message”, response => {

Dealing with messaging can really make the code much harder to read and maintain. We were looking for something friendlier, where one thread could asynchronously “call a method” on another thread and just receive back the result.

We went on to explore and test various OS packages around thread management and communication.

Along the way we found some packages that solve both the threadpool problem and the elegant RPC-like task execution on threads. A popular example was piscina. It looked all nice and dandy, but there was one showstopper. 

A critical requirement for us was to have a way for our worker threads to call some APIs exposed back on the main thread. One major use-case for that was reporting business metrics and logs from code running in the worker. Due to the way these things are widely done in Wix, we couldn’t directly do them from each of the workers, and had to go through the main thread.

So we dropped these good looking packages and looked for some different approaches. We realized that we couldn’t just take something off the shelf and plug it in.

Finally, we have reached our final setup with which we were happy.

We mixed and wired the native Workers API with two great OS packages:

  • generic-pool (npmjs) – a very solid and popular pooling API. This one helped us get our desired thread-pool feel.
  • comlink (npmjs) – a popular package mostly known for RPC-like communication in the browser (with the long-existing JS Web Workers). It recently added support for Node.js Workers. This package made inter-thread communication in our code look much more concise and elegant.

The way it now looks is now along the lines of the following:

import * as genericPool from ‘generic-pool’;
import * as Comlink from ‘comlink’;
import nodeEndpoint from ‘comlink/dist/umd/node-adapter’;

export const createThreadPool = ({
                                }): Pool<OurWorkerThread> => {
    return genericPool.createPool(
            create: () => {
                const worker = new Worker(workerPath, workerOptions);
                }, nodeEndpoint(worker));

                return {
                    workerApi: Comlink.wrap<ModuleExecutionWorkerApi>(nodeEndpoint(worker)) };
            destroy: ({ worker }: OurWorkerThread) => worker.terminate(),

And the usage in the web-server level:

const workerResponse = await workerPool.use(({ workerApi }: OurWorkerThread) =>

// … Do stuff with response

One major takeaway from the development journey was that imposing worker-threads on some existing code is by no means straightforward. Logic objects (i.e. JS functions) cannot be passed back and forth between threads, and so, sometimes considerable refactoring is needed. Clear concrete pure-data-based APIs for communication between the main thread and the workers must be defined and the code should be adjusted accordingly.


The results were amazing: we cut the number of pods by over 70% and made the entire system more stable and resilient. A direct consequence was cutting much of Wix’s infra costs accordingly.

Some numbers:

  • Our initial goal was achieved – total SSRE pod count dropped by ~70%.
    Respectively, RPM per pod improved by 153%.
  • Better SLA and a more stable application – 
    • Response time p50 : -11% 
    • Response time p95: -20%
    • Error rate decreased even further: 10x better
  • Big cut in total direct SSRE compute cost: -21%

Lessons learned and future planning:

We’ve learned that Node.js is indeed suitable also for CPU-bound high-throughput services. We managed to reduce our infra management overhead, but this modest goal turned out to be overshadowed by much more substantial gains.

The introduction of multithreading into the SSRE platform has opened the way for follow-up research of optimizations and improvements:

  • Finding the optimal number of CPU cores per machine, possibly allowing for non-constant size thread-pools.
  • Refactor the application to make workers do work that’s as pure CPU as possible.
  • Research memory sharing between threads to avoid a lot of large object cloning.
  • Apply this solution to other major Node.js-based applications in Wix.