You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Creating cross-platform (Node.js + browsers) code has never been more important, but there are still some sharp edges. fetch support was recently added, but there's another important and popular API; Web Workers. Node.js does have worker_threads, but the API differs in many ways and it's really difficult to properly bridge them. There are attempts at bridging these APIs in user-land, but the most popular one is incomplete and not actively maintained.
What is the feature you are proposing to solve the problem?
I propose adding support for Web Workers in Node.js. The Web Workers API is essential to keep apps and servers responsive by moving CPU heavy work off the main thread. I strongly feel it should be part of Node.js.
What alternatives have you considered?
Continue using one of the available polyfills, but that means larger dependency trees, more bugs, and more workaround code.
The linked module appears to mostly be adding things node workers already support (web events, data uris). Looking at MDN the only thing that really jumps out to me is type: classic/module and name.
The linked module appears to mostly be adding things node workers already support (web events, data uris). Looking at MDN the only thing that really jumps out to me is type: classic/module and name.
Also the web version only supports URLs (strings) in the constructor, while the Node.js one supports paths and URL objects.
IIRC, when @addaleax implemented worker_threads, she modeled the API on Web Workers but it was not possible to support the entire API, so it diverged in places. I'm not sure if the specifics are documented anywhere or if anything has changed.
@sindresorhus Any chance you have specific API pain points you'd highlight? If we can't do everything but we can do some things, it would be good to know what is (at least in your view) the high-priority stuff.
Reacted by Tobias Nießen, Philip Kumah, Eliaz Bobadilla and Brandon Bennett
That’s arguably a sign against inclusion in Node.js core, unless you have a reason to believe that development as part of Node.js would improve this situation (isn’t obvious to me why that would be).
she modeled the API on Web Workers but it was not possible to support the entire API, so it diverged in places
The goal was to implement an API that matches Node.js’s abilities and requirements. You can probably support all or almost all of the Web API if you try hard enough, and the Node.js API is certainly inspired by the Web API on the parent thread side. On the child thread side, you are just running code in a completely different environment to begin with.
That’s arguably a sign against inclusion in Node.js core, unless you have a reason to believe that development as part of Node.js would improve this situation (isn’t obvious to me why that would be).
Definitely have to agree with this... It could also be a sign that worker_threads are "close enough" to discourage further effort there.
I'd certainly be open to PRs that move the current worker_threads implementation closer to the standard alignment. I don't think we really need to do a new implementation of anything, just incremental changes here and there.
IIRC, when @addaleax implemented worker_threads, she modeled the API on Web Workers but it was not possible to support the entire API, so it diverged in places.
I'm curious why it was not possible to support the entire API? And what parts?
That’s arguably a sign against inclusion in Node.js core, unless you have a reason to believe that development as part of Node.js would improve this situation (isn’t obvious to me why that would be).
The maintainer released something they needed and got busy. I don't think that's evidence for whether or not it would prosper as a part of Node.js. The repo does have a lot of pull requests, which suggests people would be willing to help improve it.
Reacted by Fabio Spampinato, Hisam Fahri, Mark Malstrom, Steven, Kirill Groshkov, Corbin Crutchley, Aaron Huggins, Mark Hoad, Enzo Innocenzi, Josh A and 24 more
It could also be a sign that worker_threads are "close enough" to discourage further effort there.
Why add fetch then? http.get is close enough. Why add Web Streams? Node streams are close enough. There are huge benefits for Node.js and browser sharing some APIs. Familiarity. Code sharing. Less dependencies.
I'd certainly be open to PRs that move the current worker_threads implementation closer to the standard alignment.
Moving worker_threads closer to the Web Workers API would be a welcome change, but Node.js should still have a spec compliant Web Worker API. worker_threads cannot ever be fully spec compliant.
Reacted by JounQin, Alex Ware, Fabio Spampinato, Mark Malstrom, Ness Hernández Ojeda, Kirill Groshkov, Mark Hoad, Enzo Innocenzi, Danny Feliz, कारतोफ्फेलस्क्रिप्ट™ and 70 more
Reacted by fregante, Sasha Sirotkin, Harry Wright, Declan, Eliaz Bobadilla, Mon, Brandon Bennett, David Myers, 145a, Ghislain B. and 1 more
No, I meant that it could explain why the userland module wasn't advanced further, not offering any kind of reason why we wouldn't continue to make improvements in core. I'm all for that, just need someone to volunteer to do the work
I don't think anyone is against improving this, we're more trying to figure out what specifically you are looking for in the worker api. Like what prompted you to open this issue? That information can help us triage and understand what scope of work is needed.
Reacted by Jiawen Geng, Anna Henningsen, Tobias Nießen, sacru2red, bruhg0d, Brandon Bennett and 145a
The output doesn't show it, but it's easy to add console.log(…) calls to verify that the worker is instantiated and performs non-trivial work as desired!
That said, the process hangs because .unref() is not available (as far as I can tell). It is important for performance and correctness in our case to have a way to .unref() web workers, since:
Creating a worker is a little bit expensive (100ms to several seconds of CPU time to initialize calculations inside each worker, depending on the use case).
Our library is an abstraction whose use of web workers must not leak for basic use cases.
Without .unref(), our choices are:
Proactively terminate workers just in case they are not being used, thus incurring a significant user-facing performance penalty for some use cases.
Require users of our library to keep track of all their calls and explicitly notify us to terminate all workers once they are certain they do not need them any more. This is not an ergonomic API, and is a recipe for bugs in my experience.
bun supports .unref() (and .ref()) directly on web workers. I think this is pretty sensible, and it has worked well for us. I'd be glad to see node's web worker implementation support the same, so that we can switch to it without workarounds or caveats.
cc @nodejs/web-standards We support ref/unref on some other standard instances, like timers, do you think it's worth it to support it on the worker implementation as well?
Note that it's not web standard, and isn't support by Deno, but is supported by Bun
I've been trying to adapt code to run web workers on node-nightly, and I'm running into issues because Worker and WorkerGlobalScope are explicitly specified to inherit the EventTarget interface but the current flagged implementation does not do this. I don't think it would be possible to call it a full web worker implementation without this, and I think it would be valuable to implement it. There seems to be precedent for other web APIs like WebSocket (https://nodejs.org/learn/getting-started/websocket).
(Also note that bun and deno both implement Worker to extend EventTarget.)
EDIT: never mind, I was testing wrong because npx node-nightly has some issues on my system. I think it's actually implemented correctly.
25. EDIT: never mind, I was testing wrong because npx node-nightly has some issues on my system. I think it's actually implemented correctly.
Okay, after poking it a bunch I've found the node implementation is quite robust! I'm able to put it through non-trivial work with message passing, reference counting, multiple workers, and heavy computation, even heavily interleaved. It has given me significantly less trouble than bun or deno ever did.
I hope this is an encouraging sign that there will be no major issues from people trying out the flag and that it can be enabled by default sooner rather than later. I'm really excited for the day when it is — it will eliminate a large class of workarounds from writing portable library code.
Activity
aduh95 commentedon Jun 27, 2022
Is it something you'd be ready to implement this yourself?
/cc @nodejs/workers
JounQin commentedon Jun 27, 2022
Similar to https://www.npmjs.com/package/web-worker?
devsnek commentedon Jun 27, 2022
The linked module appears to mostly be adding things node workers already support (web events, data uris). Looking at MDN the only thing that really jumps out to me is
type: classic/moduleandname.aduh95 commentedon Jun 27, 2022
Also the web version only supports URLs (strings) in the constructor, while the Node.js one supports paths and
URLobjects.Trott commentedon Jun 27, 2022
IIRC, when @addaleax implemented worker_threads, she modeled the API on Web Workers but it was not possible to support the entire API, so it diverged in places. I'm not sure if the specifics are documented anywhere or if anything has changed.
@sindresorhus Any chance you have specific API pain points you'd highlight? If we can't do everything but we can do some things, it would be good to know what is (at least in your view) the high-priority stuff.
Trott commentedon Jun 27, 2022
@nodejs/workers
addaleax commentedon Jun 27, 2022
That’s arguably a sign against inclusion in Node.js core, unless you have a reason to believe that development as part of Node.js would improve this situation (isn’t obvious to me why that would be).
The goal was to implement an API that matches Node.js’s abilities and requirements. You can probably support all or almost all of the Web API if you try hard enough, and the Node.js API is certainly inspired by the Web API on the parent thread side. On the child thread side, you are just running code in a completely different environment to begin with.
jasnell commentedon Jun 27, 2022
Definitely have to agree with this... It could also be a sign that
worker_threadsare "close enough" to discourage further effort there.I'd certainly be open to PRs that move the current
worker_threadsimplementation closer to the standard alignment. I don't think we really need to do a new implementation of anything, just incremental changes here and there.tl;dr ... PRs welcome ;-)
sindresorhus commentedon Jun 27, 2022
No
sindresorhus commentedon Jun 27, 2022
I'm curious why it was not possible to support the entire API? And what parts?
sindresorhus commentedon Jun 27, 2022
The maintainer released something they needed and got busy. I don't think that's evidence for whether or not it would prosper as a part of Node.js. The repo does have a lot of pull requests, which suggests people would be willing to help improve it.
sindresorhus commentedon Jun 27, 2022
Why add
fetchthen?http.getis close enough. Why add Web Streams? Node streams are close enough. There are huge benefits for Node.js and browser sharing some APIs. Familiarity. Code sharing. Less dependencies.Deno supports Web Workers.
Moving
worker_threadscloser to the Web Workers API would be a welcome change, but Node.js should still have a spec compliant Web Worker API.worker_threadscannot ever be fully spec compliant.jasnell commentedon Jun 27, 2022
No, I meant that it could explain why the userland module wasn't advanced further, not offering any kind of reason why we wouldn't continue to make improvements in core. I'm all for that, just need someone to volunteer to do the work
devsnek commentedon Jun 27, 2022
I don't think anyone is against improving this, we're more trying to figure out what specifically you are looking for in the worker api. Like what prompted you to open this issue? That information can help us triage and understand what scope of work is needed.
60 remaining items
test: accomodate multi-global tests in WPT{Runner,TestSpec,Report}
lgarron commentedon Aug 21, 2026
I'm really glad to see this is mostly working on nightly!
The output doesn't show it, but it's easy to add
console.log(…)calls to verify that the worker is instantiated and performs non-trivial work as desired!That said, the process hangs because
.unref()is not available (as far as I can tell). It is important for performance and correctness in our case to have a way to.unref()web workers, since:Without
.unref(), our choices are:bunsupports.unref()(and.ref()) directly on web workers. I think this is pretty sensible, and it has worked well for us. I'd be glad to seenode's web worker implementation support the same, so that we can switch to it without workarounds or caveats.avivkeller commentedon Aug 21, 2026
cc @nodejs/web-standards We support ref/unref on some other standard instances, like timers, do you think it's worth it to support it on the worker implementation as well?
Note that it's not web standard, and isn't support by Deno, but is supported by Bun
test: accomodate multi-global tests in WPT{Runner,TestSpec,Report}
test: add opt-in process WPT runner
worker: add support for Web Workers
test: enable multi-global WPTs
worker: add wpt tests for Web Workers
test: accomodate multi-global tests in WPT{Runner,TestSpec,Report}
test: add opt-in process WPT runner
worker: add support for Web Workers
test: enable multi-global WPTs
worker: add wpt tests for Web Workers
lgarron commentedon Oct 9, 2026
I've been trying to adapt code to run web workers on
node-nightly, and I'm running into issues becauseWorkerandWorkerGlobalScopeare explicitly specified to inherit theEventTargetinterface but the current flagged implementation does not do this. I don't think it would be possible to call it a full web worker implementation without this, and I think it would be valuable to implement it. There seems to be precedent for other web APIs likeWebSocket(https://nodejs.org/learn/getting-started/websocket).(Also note that
bunanddenoboth implementWorkerto extendEventTarget.)EDIT: never mind, I was testing wrong because
npx node-nightlyhas some issues on my system. I think it's actually implemented correctly.lgarron commentedon Oct 9, 2026
Okay, after poking it a bunch I've found the
nodeimplementation is quite robust! I'm able to put it through non-trivial work with message passing, reference counting, multiple workers, and heavy computation, even heavily interleaved. It has given me significantly less trouble thanbunordenoever did.PR passing a whole bunch of tests: cubing/cubing.js#440
Library usage:
I hope this is an encouraging sign that there will be no major issues from people trying out the flag and that it can be enabled by default sooner rather than later. I'm really excited for the day when it is — it will eliminate a large class of workarounds from writing portable library code.