• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# Worker threads
2
3<!--introduced_in=v10.5.0-->
4
5> Stability: 2 - Stable
6
7<!-- source_link=lib/worker_threads.js -->
8
9The `worker_threads` module enables the use of threads that execute JavaScript
10in parallel. To access it:
11
12```js
13const worker = require('worker_threads');
14```
15
16Workers (threads) are useful for performing CPU-intensive JavaScript operations.
17They will not help much with I/O-intensive work. Node.js’s built-in asynchronous
18I/O operations are more efficient than Workers can be.
19
20Unlike `child_process` or `cluster`, `worker_threads` can share memory. They do
21so by transferring `ArrayBuffer` instances or sharing `SharedArrayBuffer`
22instances.
23
24```js
25const {
26  Worker, isMainThread, parentPort, workerData
27} = require('worker_threads');
28
29if (isMainThread) {
30  module.exports = function parseJSAsync(script) {
31    return new Promise((resolve, reject) => {
32      const worker = new Worker(__filename, {
33        workerData: script
34      });
35      worker.on('message', resolve);
36      worker.on('error', reject);
37      worker.on('exit', (code) => {
38        if (code !== 0)
39          reject(new Error(`Worker stopped with exit code ${code}`));
40      });
41    });
42  };
43} else {
44  const { parse } = require('some-js-parsing-library');
45  const script = workerData;
46  parentPort.postMessage(parse(script));
47}
48```
49
50The above example spawns a Worker thread for each `parse()` call. In actual
51practice, use a pool of Workers instead for these kinds of tasks. Otherwise, the
52overhead of creating Workers would likely exceed their benefit.
53
54When implementing a worker pool, use the [`AsyncResource`][] API to inform
55diagnostic tools (e.g. in order to provide asynchronous stack traces) about the
56correlation between tasks and their outcomes. See
57["Using `AsyncResource` for a `Worker` thread pool"][async-resource-worker-pool]
58in the `async_hooks` documentation for an example implementation.
59
60Worker threads inherit non-process-specific options by default. Refer to
61[`Worker constructor options`][] to know how to customize worker thread options,
62specifically `argv` and `execArgv` options.
63
64## `worker.getEnvironmentData(key)`
65<!-- YAML
66added: v14.18.0
67-->
68
69> Stability: 1 - Experimental
70
71* `key` {any} Any arbitrary, cloneable JavaScript value that can be used as a
72  {Map} key.
73* Returns: {any}
74
75Within a worker thread, `worker.getEnvironmentData()` returns a clone
76of data passed to the spawning thread's `worker.setEnvironmentData()`.
77Every new `Worker` receives its own copy of the environment data
78automatically.
79
80```js
81const {
82  Worker,
83  isMainThread,
84  setEnvironmentData,
85  getEnvironmentData,
86} = require('worker_threads');
87
88if (isMainThread) {
89  setEnvironmentData('Hello', 'World!');
90  const worker = new Worker(__filename);
91} else {
92  console.log(getEnvironmentData('Hello'));  // Prints 'World!'.
93}
94```
95
96## `worker.isMainThread`
97<!-- YAML
98added: v10.5.0
99-->
100
101* {boolean}
102
103Is `true` if this code is not running inside of a [`Worker`][] thread.
104
105```js
106const { Worker, isMainThread } = require('worker_threads');
107
108if (isMainThread) {
109  // This re-loads the current file inside a Worker instance.
110  new Worker(__filename);
111} else {
112  console.log('Inside Worker!');
113  console.log(isMainThread);  // Prints 'false'.
114}
115```
116
117## `worker.markAsUntransferable(object)`
118<!-- YAML
119added: v14.5.0
120-->
121
122Mark an object as not transferable. If `object` occurs in the transfer list of
123a [`port.postMessage()`][] call, it will be ignored.
124
125In particular, this makes sense for objects that can be cloned, rather than
126transferred, and which are used by other objects on the sending side.
127For example, Node.js marks the `ArrayBuffer`s it uses for its
128[`Buffer` pool][`Buffer.allocUnsafe()`] with this.
129
130This operation cannot be undone.
131
132```js
133const { MessageChannel, markAsUntransferable } = require('worker_threads');
134
135const pooledBuffer = new ArrayBuffer(8);
136const typedArray1 = new Uint8Array(pooledBuffer);
137const typedArray2 = new Float64Array(pooledBuffer);
138
139markAsUntransferable(pooledBuffer);
140
141const { port1 } = new MessageChannel();
142port1.postMessage(typedArray1, [ typedArray1.buffer ]);
143
144// The following line prints the contents of typedArray1 -- it still owns
145// its memory and has been cloned, not transferred. Without
146// `markAsUntransferable()`, this would print an empty Uint8Array.
147// typedArray2 is intact as well.
148console.log(typedArray1);
149console.log(typedArray2);
150```
151
152There is no equivalent to this API in browsers.
153
154## `worker.moveMessagePortToContext(port, contextifiedSandbox)`
155<!-- YAML
156added: v11.13.0
157-->
158
159* `port` {MessagePort} The message port which will be transferred.
160* `contextifiedSandbox` {Object} A [contextified][] object as returned by the
161  `vm.createContext()` method.
162
163* Returns: {MessagePort}
164
165Transfer a `MessagePort` to a different [`vm`][] Context. The original `port`
166object will be rendered unusable, and the returned `MessagePort` instance will
167take its place.
168
169The returned `MessagePort` will be an object in the target context, and will
170inherit from its global `Object` class. Objects passed to the
171[`port.onmessage()`][] listener will also be created in the target context
172and inherit from its global `Object` class.
173
174However, the created `MessagePort` will no longer inherit from
175[`EventTarget`][], and only [`port.onmessage()`][] can be used to receive
176events using it.
177
178## `worker.parentPort`
179<!-- YAML
180added: v10.5.0
181-->
182
183* {null|MessagePort}
184
185If this thread was spawned as a [`Worker`][], this will be a [`MessagePort`][]
186allowing communication with the parent thread. Messages sent using
187`parentPort.postMessage()` will be available in the parent thread
188using `worker.on('message')`, and messages sent from the parent thread
189using `worker.postMessage()` will be available in this thread using
190`parentPort.on('message')`.
191
192```js
193const { Worker, isMainThread, parentPort } = require('worker_threads');
194
195if (isMainThread) {
196  const worker = new Worker(__filename);
197  worker.once('message', (message) => {
198    console.log(message);  // Prints 'Hello, world!'.
199  });
200  worker.postMessage('Hello, world!');
201} else {
202  // When a message from the parent thread is received, send it back:
203  parentPort.once('message', (message) => {
204    parentPort.postMessage(message);
205  });
206}
207```
208
209## `worker.receiveMessageOnPort(port)`
210<!-- YAML
211added: v12.3.0
212-->
213
214* `port` {MessagePort}
215
216* Returns: {Object|undefined}
217
218Receive a single message from a given `MessagePort`. If no message is available,
219`undefined` is returned, otherwise an object with a single `message` property
220that contains the message payload, corresponding to the oldest message in the
221`MessagePort`’s queue.
222
223```js
224const { MessageChannel, receiveMessageOnPort } = require('worker_threads');
225const { port1, port2 } = new MessageChannel();
226port1.postMessage({ hello: 'world' });
227
228console.log(receiveMessageOnPort(port2));
229// Prints: { message: { hello: 'world' } }
230console.log(receiveMessageOnPort(port2));
231// Prints: undefined
232```
233
234When this function is used, no `'message'` event will be emitted and the
235`onmessage` listener will not be invoked.
236
237## `worker.resourceLimits`
238<!-- YAML
239added:
240 - v13.2.0
241 - v12.16.0
242-->
243
244* {Object}
245  * `maxYoungGenerationSizeMb` {number}
246  * `maxOldGenerationSizeMb` {number}
247  * `codeRangeSizeMb` {number}
248  * `stackSizeMb` {number}
249
250Provides the set of JS engine resource constraints inside this Worker thread.
251If the `resourceLimits` option was passed to the [`Worker`][] constructor,
252this matches its values.
253
254If this is used in the main thread, its value is an empty object.
255
256## `worker.SHARE_ENV`
257<!-- YAML
258added: v11.14.0
259-->
260
261* {symbol}
262
263A special value that can be passed as the `env` option of the [`Worker`][]
264constructor, to indicate that the current thread and the Worker thread should
265share read and write access to the same set of environment variables.
266
267```js
268const { Worker, SHARE_ENV } = require('worker_threads');
269new Worker('process.env.SET_IN_WORKER = "foo"', { eval: true, env: SHARE_ENV })
270  .on('exit', () => {
271    console.log(process.env.SET_IN_WORKER);  // Prints 'foo'.
272  });
273```
274
275## `worker.setEnvironmentData(key[, value])`
276<!-- YAML
277added: v14.18.0
278-->
279
280> Stability: 1 - Experimental
281
282* `key` {any} Any arbitrary, cloneable JavaScript value that can be used as a
283  {Map} key.
284* `value` {any} Any arbitrary, cloneable JavaScript value that will be cloned
285  and passed automatically to all new `Worker` instances. If `value` is passed
286  as `undefined`, any previously set value for the `key` will be deleted.
287
288The `worker.setEnvironmentData()` API sets the content of
289`worker.getEnvironmentData()` in the current thread and all new `Worker`
290instances spawned from the current context.
291
292## `worker.threadId`
293<!-- YAML
294added: v10.5.0
295-->
296
297* {integer}
298
299An integer identifier for the current thread. On the corresponding worker object
300(if there is any), it is available as [`worker.threadId`][].
301This value is unique for each [`Worker`][] instance inside a single process.
302
303## `worker.workerData`
304<!-- YAML
305added: v10.5.0
306-->
307
308An arbitrary JavaScript value that contains a clone of the data passed
309to this thread’s `Worker` constructor.
310
311The data is cloned as if using [`postMessage()`][`port.postMessage()`],
312according to the [HTML structured clone algorithm][].
313
314```js
315const { Worker, isMainThread, workerData } = require('worker_threads');
316
317if (isMainThread) {
318  const worker = new Worker(__filename, { workerData: 'Hello, world!' });
319} else {
320  console.log(workerData);  // Prints 'Hello, world!'.
321}
322```
323
324## Class: `MessageChannel`
325<!-- YAML
326added: v10.5.0
327-->
328
329Instances of the `worker.MessageChannel` class represent an asynchronous,
330two-way communications channel.
331The `MessageChannel` has no methods of its own. `new MessageChannel()`
332yields an object with `port1` and `port2` properties, which refer to linked
333[`MessagePort`][] instances.
334
335```js
336const { MessageChannel } = require('worker_threads');
337
338const { port1, port2 } = new MessageChannel();
339port1.on('message', (message) => console.log('received', message));
340port2.postMessage({ foo: 'bar' });
341// Prints: received { foo: 'bar' } from the `port1.on('message')` listener
342```
343
344## Class: `MessagePort`
345<!-- YAML
346added: v10.5.0
347changes:
348  - version:
349    - v14.7.0
350    pr-url: https://github.com/nodejs/node/pull/34057
351    description: This class now inherits from `EventTarget` rather than
352                 from `EventEmitter`.
353-->
354
355* Extends: {EventTarget}
356
357Instances of the `worker.MessagePort` class represent one end of an
358asynchronous, two-way communications channel. It can be used to transfer
359structured data, memory regions and other `MessagePort`s between different
360[`Worker`][]s.
361
362This implementation matches [browser `MessagePort`][]s.
363
364### Event: `'close'`
365<!-- YAML
366added: v10.5.0
367-->
368
369The `'close'` event is emitted once either side of the channel has been
370disconnected.
371
372```js
373const { MessageChannel } = require('worker_threads');
374const { port1, port2 } = new MessageChannel();
375
376// Prints:
377//   foobar
378//   closed!
379port2.on('message', (message) => console.log(message));
380port2.on('close', () => console.log('closed!'));
381
382port1.postMessage('foobar');
383port1.close();
384```
385
386### Event: `'message'`
387<!-- YAML
388added: v10.5.0
389-->
390
391* `value` {any} The transmitted value
392
393The `'message'` event is emitted for any incoming message, containing the cloned
394input of [`port.postMessage()`][].
395
396Listeners on this event will receive a clone of the `value` parameter as passed
397to `postMessage()` and no further arguments.
398
399### Event: `'messageerror'`
400<!-- YAML
401added: v14.5.0
402-->
403
404* `error` {Error} An Error object
405
406The `'messageerror'` event is emitted when deserializing a message failed.
407
408Currently, this event is emitted when there is an error occurring while
409instantiating the posted JS object on the receiving end. Such situations
410are rare, but can happen, for instance, when certain Node.js API objects
411are received in a `vm.Context` (where Node.js APIs are currently
412unavailable).
413
414### `port.close()`
415<!-- YAML
416added: v10.5.0
417-->
418
419Disables further sending of messages on either side of the connection.
420This method can be called when no further communication will happen over this
421`MessagePort`.
422
423The [`'close'` event][] will be emitted on both `MessagePort` instances that
424are part of the channel.
425
426### `port.postMessage(value[, transferList])`
427<!-- YAML
428added: v10.5.0
429changes:
430  - version: v14.18.0
431    pr-url: https://github.com/nodejs/node/pull/37917
432    description: Add 'BlockList' to the list of cloneable types.
433  - version: v14.18.0
434    pr-url: https://github.com/nodejs/node/pull/37155
435    description: Add 'Histogram' types to the list of cloneable types.
436  - version: v14.5.0
437    pr-url: https://github.com/nodejs/node/pull/33360
438    description: Added `KeyObject` to the list of cloneable types.
439  - version: v14.5.0
440    pr-url: https://github.com/nodejs/node/pull/33772
441    description: Added `FileHandle` to the list of transferable types.
442-->
443
444* `value` {any}
445* `transferList` {Object[]}
446
447Sends a JavaScript value to the receiving side of this channel.
448`value` will be transferred in a way which is compatible with
449the [HTML structured clone algorithm][].
450
451In particular, the significant differences to `JSON` are:
452
453* `value` may contain circular references.
454* `value` may contain instances of builtin JS types such as `RegExp`s,
455  `BigInt`s, `Map`s, `Set`s, etc.
456* `value` may contain typed arrays, both using `ArrayBuffer`s
457   and `SharedArrayBuffer`s.
458* `value` may contain [`WebAssembly.Module`][] instances.
459* `value` may not contain native (C++-backed) objects other than:
460  * {FileHandle}s,
461  * {Histogram}s,
462  * {KeyObject}s,
463  * {MessagePort}s,
464  * {net.BlockList}s,
465  * {net.SocketAddress}es,
466
467```js
468const { MessageChannel } = require('worker_threads');
469const { port1, port2 } = new MessageChannel();
470
471port1.on('message', (message) => console.log(message));
472
473const circularData = {};
474circularData.foo = circularData;
475// Prints: { foo: [Circular] }
476port2.postMessage(circularData);
477```
478
479`transferList` may be a list of [`ArrayBuffer`][], [`MessagePort`][] and
480[`FileHandle`][] objects.
481After transferring, they will not be usable on the sending side of the channel
482anymore (even if they are not contained in `value`). Unlike with
483[child processes][], transferring handles such as network sockets is currently
484not supported.
485
486If `value` contains [`SharedArrayBuffer`][] instances, those will be accessible
487from either thread. They cannot be listed in `transferList`.
488
489`value` may still contain `ArrayBuffer` instances that are not in
490`transferList`; in that case, the underlying memory is copied rather than moved.
491
492```js
493const { MessageChannel } = require('worker_threads');
494const { port1, port2 } = new MessageChannel();
495
496port1.on('message', (message) => console.log(message));
497
498const uint8Array = new Uint8Array([ 1, 2, 3, 4 ]);
499// This posts a copy of `uint8Array`:
500port2.postMessage(uint8Array);
501// This does not copy data, but renders `uint8Array` unusable:
502port2.postMessage(uint8Array, [ uint8Array.buffer ]);
503
504// The memory for the `sharedUint8Array` will be accessible from both the
505// original and the copy received by `.on('message')`:
506const sharedUint8Array = new Uint8Array(new SharedArrayBuffer(4));
507port2.postMessage(sharedUint8Array);
508
509// This transfers a freshly created message port to the receiver.
510// This can be used, for example, to create communication channels between
511// multiple `Worker` threads that are children of the same parent thread.
512const otherChannel = new MessageChannel();
513port2.postMessage({ port: otherChannel.port1 }, [ otherChannel.port1 ]);
514```
515
516Because the object cloning uses the structured clone algorithm,
517non-enumerable properties, property accessors, and object prototypes are
518not preserved. In particular, [`Buffer`][] objects will be read as
519plain [`Uint8Array`][]s on the receiving side.
520
521The message object will be cloned immediately, and can be modified after
522posting without having side effects.
523
524For more information on the serialization and deserialization mechanisms
525behind this API, see the [serialization API of the `v8` module][v8.serdes].
526
527#### Considerations when transferring TypedArrays and Buffers
528
529All `TypedArray` and `Buffer` instances are views over an underlying
530`ArrayBuffer`. That is, it is the `ArrayBuffer` that actually stores
531the raw data while the `TypedArray` and `Buffer` objects provide a
532way of viewing and manipulating the data. It is possible and common
533for multiple views to be created over the same `ArrayBuffer` instance.
534Great care must be taken when using a transfer list to transfer an
535`ArrayBuffer` as doing so will cause all `TypedArray` and `Buffer`
536instances that share that same `ArrayBuffer` to become unusable.
537
538```js
539const ab = new ArrayBuffer(10);
540
541const u1 = new Uint8Array(ab);
542const u2 = new Uint16Array(ab);
543
544console.log(u2.length);  // prints 5
545
546port.postMessage(u1, [u1.buffer]);
547
548console.log(u2.length);  // prints 0
549```
550
551For `Buffer` instances, specifically, whether the underlying
552`ArrayBuffer` can be transferred or cloned depends entirely on how
553instances were created, which often cannot be reliably determined.
554
555An `ArrayBuffer` can be marked with [`markAsUntransferable()`][] to indicate
556that it should always be cloned and never transferred.
557
558Depending on how a `Buffer` instance was created, it may or may
559not own its underlying `ArrayBuffer`. An `ArrayBuffer` must not
560be transferred unless it is known that the `Buffer` instance
561owns it. In particular, for `Buffer`s created from the internal
562`Buffer` pool (using, for instance `Buffer.from()` or `Buffer.alloc()`),
563transferring them is not possible and they will always be cloned,
564which sends a copy of the entire `Buffer` pool.
565This behavior may come with unintended higher memory
566usage and possible security concerns.
567
568See [`Buffer.allocUnsafe()`][] for more details on `Buffer` pooling.
569
570The `ArrayBuffer`s for `Buffer` instances created using
571`Buffer.alloc()` or `Buffer.allocUnsafeSlow()` can always be
572transferred but doing so will render all other existing views of
573those `ArrayBuffer`s unusable.
574
575### `port.ref()`
576<!-- YAML
577added: v10.5.0
578-->
579
580Opposite of `unref()`. Calling `ref()` on a previously `unref()`ed port will
581*not* let the program exit if it's the only active handle left (the default
582behavior). If the port is `ref()`ed, calling `ref()` again will have no effect.
583
584If listeners are attached or removed using `.on('message')`, the port will
585be `ref()`ed and `unref()`ed automatically depending on whether
586listeners for the event exist.
587
588### `port.start()`
589<!-- YAML
590added: v10.5.0
591-->
592
593Starts receiving messages on this `MessagePort`. When using this port
594as an event emitter, this will be called automatically once `'message'`
595listeners are attached.
596
597This method exists for parity with the Web `MessagePort` API. In Node.js,
598it is only useful for ignoring messages when no event listener is present.
599Node.js also diverges in its handling of `.onmessage`. Setting it will
600automatically call `.start()`, but unsetting it will let messages queue up
601until a new handler is set or the port is discarded.
602
603### `port.unref()`
604<!-- YAML
605added: v10.5.0
606-->
607
608Calling `unref()` on a port will allow the thread to exit if this is the only
609active handle in the event system. If the port is already `unref()`ed calling
610`unref()` again will have no effect.
611
612If listeners are attached or removed using `.on('message')`, the port will
613be `ref()`ed and `unref()`ed automatically depending on whether
614listeners for the event exist.
615
616## Class: `Worker`
617<!-- YAML
618added: v10.5.0
619-->
620
621* Extends: {EventEmitter}
622
623The `Worker` class represents an independent JavaScript execution thread.
624Most Node.js APIs are available inside of it.
625
626Notable differences inside a Worker environment are:
627
628* The [`process.stdin`][], [`process.stdout`][] and [`process.stderr`][]
629  may be redirected by the parent thread.
630* The [`require('worker_threads').isMainThread`][] property is set to `false`.
631* The [`require('worker_threads').parentPort`][] message port is available.
632* [`process.exit()`][] does not stop the whole program, just the single thread,
633  and [`process.abort()`][] is not available.
634* [`process.chdir()`][] and `process` methods that set group or user ids
635  are not available.
636* [`process.env`][] is a copy of the parent thread's environment variables,
637  unless otherwise specified. Changes to one copy will not be visible in other
638  threads, and will not be visible to native add-ons (unless
639  [`worker.SHARE_ENV`][] has been passed as the `env` option to the
640  [`Worker`][] constructor).
641* [`process.title`][] cannot be modified.
642* Signals will not be delivered through [`process.on('...')`][Signals events].
643* Execution may stop at any point as a result of [`worker.terminate()`][]
644  being invoked.
645* IPC channels from parent processes are not accessible.
646* The [`trace_events`][] module is not supported.
647* Native add-ons can only be loaded from multiple threads if they fulfill
648  [certain conditions][Addons worker support].
649
650Creating `Worker` instances inside of other `Worker`s is possible.
651
652Like [Web Workers][] and the [`cluster` module][], two-way communication can be
653achieved through inter-thread message passing. Internally, a `Worker` has a
654built-in pair of [`MessagePort`][]s that are already associated with each other
655when the `Worker` is created. While the `MessagePort` object on the parent side
656is not directly exposed, its functionalities are exposed through
657[`worker.postMessage()`][] and the [`worker.on('message')`][] event
658on the `Worker` object for the parent thread.
659
660To create custom messaging channels (which is encouraged over using the default
661global channel because it facilitates separation of concerns), users can create
662a `MessageChannel` object on either thread and pass one of the
663`MessagePort`s on that `MessageChannel` to the other thread through a
664pre-existing channel, such as the global one.
665
666See [`port.postMessage()`][] for more information on how messages are passed,
667and what kind of JavaScript values can be successfully transported through
668the thread barrier.
669
670```js
671const assert = require('assert');
672const {
673  Worker, MessageChannel, MessagePort, isMainThread, parentPort
674} = require('worker_threads');
675if (isMainThread) {
676  const worker = new Worker(__filename);
677  const subChannel = new MessageChannel();
678  worker.postMessage({ hereIsYourPort: subChannel.port1 }, [subChannel.port1]);
679  subChannel.port2.on('message', (value) => {
680    console.log('received:', value);
681  });
682} else {
683  parentPort.once('message', (value) => {
684    assert(value.hereIsYourPort instanceof MessagePort);
685    value.hereIsYourPort.postMessage('the worker is sending this');
686    value.hereIsYourPort.close();
687  });
688}
689```
690
691### `new Worker(filename[, options])`
692<!-- YAML
693added: v10.5.0
694changes:
695  - version: v14.9.0
696    pr-url: https://github.com/nodejs/node/pull/34584
697    description: The `filename` parameter can be a WHATWG `URL` object using
698                 `data:` protocol.
699  - version: v14.9.0
700    pr-url: https://github.com/nodejs/node/pull/34394
701    description: The `trackUnmanagedFds` option was set to `true` by default.
702  - version:
703    - v14.6.0
704    pr-url: https://github.com/nodejs/node/pull/34303
705    description: The `trackUnmanagedFds` option was introduced.
706  - version: v14.0.0
707    pr-url: https://github.com/nodejs/node/pull/32278
708    description: The `transferList` option was introduced.
709  - version: v13.12.0
710    pr-url: https://github.com/nodejs/node/pull/31664
711    description: The `filename` parameter can be a WHATWG `URL` object using
712                 `file:` protocol.
713  - version:
714     - v13.4.0
715     - v12.16.0
716    pr-url: https://github.com/nodejs/node/pull/30559
717    description: The `argv` option was introduced.
718  - version:
719     - v13.2.0
720     - v12.16.0
721    pr-url: https://github.com/nodejs/node/pull/26628
722    description: The `resourceLimits` option was introduced.
723-->
724
725* `filename` {string|URL} The path to the Worker’s main script or module. Must
726  be either an absolute path or a relative path (i.e. relative to the
727  current working directory) starting with `./` or `../`, or a WHATWG `URL`
728  object using `file:` or `data:` protocol.
729  When using a [`data:` URL][], the data is interpreted based on MIME type using
730  the [ECMAScript module loader][].
731  If `options.eval` is `true`, this is a string containing JavaScript code
732  rather than a path.
733* `options` {Object}
734  * `argv` {any[]} List of arguments which would be stringified and appended to
735    `process.argv` in the worker. This is mostly similar to the `workerData`
736    but the values will be available on the global `process.argv` as if they
737    were passed as CLI options to the script.
738  * `env` {Object} If set, specifies the initial value of `process.env` inside
739    the Worker thread. As a special value, [`worker.SHARE_ENV`][] may be used
740    to specify that the parent thread and the child thread should share their
741    environment variables; in that case, changes to one thread’s `process.env`
742    object will affect the other thread as well. **Default:** `process.env`.
743  * `eval` {boolean} If `true` and the first argument is a `string`, interpret
744    the first argument to the constructor as a script that is executed once the
745    worker is online.
746  * `execArgv` {string[]} List of node CLI options passed to the worker.
747    V8 options (such as `--max-old-space-size`) and options that affect the
748    process (such as `--title`) are not supported. If set, this will be provided
749    as [`process.execArgv`][] inside the worker. By default, options will be
750    inherited from the parent thread.
751  * `stdin` {boolean} If this is set to `true`, then `worker.stdin` will
752    provide a writable stream whose contents will appear as `process.stdin`
753    inside the Worker. By default, no data is provided.
754  * `stdout` {boolean} If this is set to `true`, then `worker.stdout` will
755    not automatically be piped through to `process.stdout` in the parent.
756  * `stderr` {boolean} If this is set to `true`, then `worker.stderr` will
757    not automatically be piped through to `process.stderr` in the parent.
758  * `workerData` {any} Any JavaScript value that will be cloned and made
759    available as [`require('worker_threads').workerData`][]. The cloning will
760    occur as described in the [HTML structured clone algorithm][], and an error
761    will be thrown if the object cannot be cloned (e.g. because it contains
762    `function`s).
763  * `trackUnmanagedFds` {boolean} If this is set to `true`, then the Worker will
764    track raw file descriptors managed through [`fs.open()`][] and
765    [`fs.close()`][], and close them when the Worker exits, similar to other
766    resources like network sockets or file descriptors managed through
767    the [`FileHandle`][] API. This option is automatically inherited by all
768    nested `Worker`s. **Default**: `false`.
769  * `transferList` {Object[]} If one or more `MessagePort`-like objects
770    are passed in `workerData`, a `transferList` is required for those
771    items or [`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`][] will be thrown.
772    See [`port.postMessage()`][] for more information.
773  * `resourceLimits` {Object} An optional set of resource limits for the new
774    JS engine instance. Reaching these limits will lead to termination of the
775    `Worker` instance. These limits only affect the JS engine, and no external
776    data, including no `ArrayBuffer`s. Even if these limits are set, the process
777    may still abort if it encounters a global out-of-memory situation.
778    * `maxOldGenerationSizeMb` {number} The maximum size of the main heap in MB.
779    * `maxYoungGenerationSizeMb` {number} The maximum size of a heap space for
780      recently created objects.
781    * `codeRangeSizeMb` {number} The size of a pre-allocated memory range
782      used for generated code.
783    * `stackSizeMb` {number} The default maximum stack size for the thread.
784      Small values may lead to unusable Worker instances. **Default:** `4`.
785
786### Event: `'error'`
787<!-- YAML
788added: v10.5.0
789-->
790
791* `err` {Error}
792
793The `'error'` event is emitted if the worker thread throws an uncaught
794exception. In that case, the worker will be terminated.
795
796### Event: `'exit'`
797<!-- YAML
798added: v10.5.0
799-->
800
801* `exitCode` {integer}
802
803The `'exit'` event is emitted once the worker has stopped. If the worker
804exited by calling [`process.exit()`][], the `exitCode` parameter will be the
805passed exit code. If the worker was terminated, the `exitCode` parameter will
806be `1`.
807
808This is the final event emitted by any `Worker` instance.
809
810### Event: `'message'`
811<!-- YAML
812added: v10.5.0
813-->
814
815* `value` {any} The transmitted value
816
817The `'message'` event is emitted when the worker thread has invoked
818[`require('worker_threads').parentPort.postMessage()`][].
819See the [`port.on('message')`][] event for more details.
820
821All messages sent from the worker thread will be emitted before the
822[`'exit'` event][] is emitted on the `Worker` object.
823
824### Event: `'messageerror'`
825<!-- YAML
826added: v14.5.0
827-->
828
829* `error` {Error} An Error object
830
831The `'messageerror'` event is emitted when deserializing a message failed.
832
833### Event: `'online'`
834<!-- YAML
835added: v10.5.0
836-->
837
838The `'online'` event is emitted when the worker thread has started executing
839JavaScript code.
840
841### `worker.getHeapSnapshot()`
842<!-- YAML
843added: v13.9.0
844-->
845
846* Returns: {Promise} A promise for a Readable Stream containing
847  a V8 heap snapshot
848
849Returns a readable stream for a V8 snapshot of the current state of the Worker.
850See [`v8.getHeapSnapshot()`][] for more details.
851
852If the Worker thread is no longer running, which may occur before the
853[`'exit'` event][] is emitted, the returned `Promise` will be rejected
854immediately with an [`ERR_WORKER_NOT_RUNNING`][] error.
855
856### `worker.performance`
857<!-- YAML
858added: v14.17.0
859-->
860
861An object that can be used to query performance information from a worker
862instance. Similar to [`perf_hooks.performance`][].
863
864#### `performance.eventLoopUtilization([utilization1[, utilization2]])`
865<!-- YAML
866added: v14.17.0
867-->
868
869* `utilization1` {Object} The result of a previous call to
870    `eventLoopUtilization()`.
871* `utilization2` {Object} The result of a previous call to
872    `eventLoopUtilization()` prior to `utilization1`.
873* Returns {Object}
874  * `idle` {number}
875  * `active` {number}
876  * `utilization` {number}
877
878The same call as [`perf_hooks` `eventLoopUtilization()`][], except the values
879of the worker instance are returned.
880
881One difference is that, unlike the main thread, bootstrapping within a worker
882is done within the event loop. So the event loop utilization will be
883immediately available once the worker's script begins execution.
884
885An `idle` time that does not increase does not indicate that the worker is
886stuck in bootstrap. The following examples shows how the worker's entire
887lifetime will never accumulate any `idle` time, but is still be able to process
888messages.
889
890```js
891const { Worker, isMainThread, parentPort } = require('worker_threads');
892
893if (isMainThread) {
894  const worker = new Worker(__filename);
895  setInterval(() => {
896    worker.postMessage('hi');
897    console.log(worker.performance.eventLoopUtilization());
898  }, 100).unref();
899  return;
900}
901
902parentPort.on('message', () => console.log('msg')).unref();
903(function r(n) {
904  if (--n < 0) return;
905  const t = Date.now();
906  while (Date.now() - t < 300);
907  setImmediate(r, n);
908})(10);
909```
910
911The event loop utilization of a worker is available only after the [`'online'`
912event][] emitted, and if called before this, or after the [`'exit'`
913event][], then all properties have the value of `0`.
914
915### `worker.postMessage(value[, transferList])`
916<!-- YAML
917added: v10.5.0
918-->
919
920* `value` {any}
921* `transferList` {Object[]}
922
923Send a message to the worker that will be received via
924[`require('worker_threads').parentPort.on('message')`][].
925See [`port.postMessage()`][] for more details.
926
927### `worker.ref()`
928<!-- YAML
929added: v10.5.0
930-->
931
932Opposite of `unref()`, calling `ref()` on a previously `unref()`ed worker will
933*not* let the program exit if it's the only active handle left (the default
934behavior). If the worker is `ref()`ed, calling `ref()` again will have
935no effect.
936
937### `worker.resourceLimits`
938<!-- YAML
939added:
940 - v13.2.0
941 - v12.16.0
942-->
943
944* {Object}
945  * `maxYoungGenerationSizeMb` {number}
946  * `maxOldGenerationSizeMb` {number}
947  * `codeRangeSizeMb` {number}
948  * `stackSizeMb` {number}
949
950Provides the set of JS engine resource constraints for this Worker thread.
951If the `resourceLimits` option was passed to the [`Worker`][] constructor,
952this matches its values.
953
954If the worker has stopped, the return value is an empty object.
955
956### `worker.stderr`
957<!-- YAML
958added: v10.5.0
959-->
960
961* {stream.Readable}
962
963This is a readable stream which contains data written to [`process.stderr`][]
964inside the worker thread. If `stderr: true` was not passed to the
965[`Worker`][] constructor, then data will be piped to the parent thread's
966[`process.stderr`][] stream.
967
968### `worker.stdin`
969<!-- YAML
970added: v10.5.0
971-->
972
973* {null|stream.Writable}
974
975If `stdin: true` was passed to the [`Worker`][] constructor, this is a
976writable stream. The data written to this stream will be made available in
977the worker thread as [`process.stdin`][].
978
979### `worker.stdout`
980<!-- YAML
981added: v10.5.0
982-->
983
984* {stream.Readable}
985
986This is a readable stream which contains data written to [`process.stdout`][]
987inside the worker thread. If `stdout: true` was not passed to the
988[`Worker`][] constructor, then data will be piped to the parent thread's
989[`process.stdout`][] stream.
990
991### `worker.terminate()`
992<!-- YAML
993added: v10.5.0
994changes:
995  - version: v12.5.0
996    pr-url: https://github.com/nodejs/node/pull/28021
997    description: This function now returns a Promise.
998                 Passing a callback is deprecated, and was useless up to this
999                 version, as the Worker was actually terminated synchronously.
1000                 Terminating is now a fully asynchronous operation.
1001-->
1002
1003* Returns: {Promise}
1004
1005Stop all JavaScript execution in the worker thread as soon as possible.
1006Returns a Promise for the exit code that is fulfilled when the
1007[`'exit'` event][] is emitted.
1008
1009### `worker.threadId`
1010<!-- YAML
1011added: v10.5.0
1012-->
1013
1014* {integer}
1015
1016An integer identifier for the referenced thread. Inside the worker thread,
1017it is available as [`require('worker_threads').threadId`][].
1018This value is unique for each `Worker` instance inside a single process.
1019
1020### `worker.unref()`
1021<!-- YAML
1022added: v10.5.0
1023-->
1024
1025Calling `unref()` on a worker will allow the thread to exit if this is the only
1026active handle in the event system. If the worker is already `unref()`ed calling
1027`unref()` again will have no effect.
1028
1029## Notes
1030
1031### Synchronous blocking of stdio
1032
1033`Worker`s utilize message passing via {MessagePort} to implement interactions
1034with `stdio`. This means that `stdio` output originating from a `Worker` can
1035get blocked by synchronous code on the receiving end that is blocking the
1036Node.js event loop.
1037
1038```mjs
1039import {
1040  Worker,
1041  isMainThread,
1042} from 'worker_threads';
1043
1044if (isMainThread) {
1045  new Worker(new URL(import.meta.url));
1046  for (let n = 0; n < 1e10; n++) {}
1047} else {
1048  // This output will be blocked by the for loop in the main thread.
1049  console.log('foo');
1050}
1051```
1052
1053```cjs
1054'use strict';
1055
1056const {
1057  Worker,
1058  isMainThread,
1059} = require('worker_threads');
1060
1061if (isMainThread) {
1062  new Worker(__filename);
1063  for (let n = 0; n < 1e10; n++) {}
1064} else {
1065  // This output will be blocked by the for loop in the main thread.
1066  console.log('foo');
1067}
1068```
1069
1070### Launching worker threads from preload scripts
1071
1072Take care when launching worker threads from preload scripts (scripts loaded
1073and run using the `-r` command line flag). Unless the `execArgv` option is
1074explicitly set, new Worker threads automatically inherit the command line flags
1075from the running process and will preload the same preload scripts as the main
1076thread. If the preload script unconditionally launches a worker thread, every
1077thread spawned will spawn another until the application crashes.
1078
1079[Addons worker support]: addons.md#addons_worker_support
1080[ECMAScript module loader]: esm.md#esm_data_imports
1081[HTML structured clone algorithm]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Structured_clone_algorithm
1082[Signals events]: process.md#process_signal_events
1083[Web Workers]: https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API
1084[`'close'` event]: #worker_threads_event_close
1085[`'exit'` event]: #worker_threads_event_exit
1086[`'online'` event]: #worker_threads_event_online
1087[`ArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer
1088[`AsyncResource`]: async_hooks.md#async_hooks_class_asyncresource
1089[`Buffer.allocUnsafe()`]: buffer.md#buffer_static_method_buffer_allocunsafe_size
1090[`Buffer`]: buffer.md
1091[`ERR_MISSING_MESSAGE_PORT_IN_TRANSFER_LIST`]: errors.md#errors_err_missing_message_port_in_transfer_list
1092[`ERR_WORKER_NOT_RUNNING`]: errors.md#ERR_WORKER_NOT_RUNNING
1093[`EventTarget`]: https://developer.mozilla.org/en-US/docs/Web/API/EventTarget
1094[`FileHandle`]: fs.md#fs_class_filehandle
1095[`MessagePort`]: #worker_threads_class_messageport
1096[`SharedArrayBuffer`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer
1097[`Uint8Array`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array
1098[`WebAssembly.Module`]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WebAssembly/Module
1099[`Worker constructor options`]: #worker_threads_new_worker_filename_options
1100[`Worker`]: #worker_threads_class_worker
1101[`cluster` module]: cluster.md
1102[`data:` URL]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URIs
1103[`fs.close()`]: fs.md#fs_fs_close_fd_callback
1104[`fs.open()`]: fs.md#fs_fs_open_path_flags_mode_callback
1105[`markAsUntransferable()`]: #worker_threads_worker_markasuntransferable_object
1106[`perf_hooks.performance`]: perf_hooks.md#perf_hooks_perf_hooks_performance
1107[`perf_hooks` `eventLoopUtilization()`]: perf_hooks.md#perf_hooks_performance_eventlooputilization_utilization1_utilization2
1108[`port.on('message')`]: #worker_threads_event_message
1109[`port.onmessage()`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort/onmessage
1110[`port.postMessage()`]: #worker_threads_port_postmessage_value_transferlist
1111[`process.abort()`]: process.md#process_process_abort
1112[`process.chdir()`]: process.md#process_process_chdir_directory
1113[`process.env`]: process.md#process_process_env
1114[`process.execArgv`]: process.md#process_process_execargv
1115[`process.exit()`]: process.md#process_process_exit_code
1116[`process.stderr`]: process.md#process_process_stderr
1117[`process.stdin`]: process.md#process_process_stdin
1118[`process.stdout`]: process.md#process_process_stdout
1119[`process.title`]: process.md#process_process_title
1120[`require('worker_threads').isMainThread`]: #worker_threads_worker_ismainthread
1121[`require('worker_threads').parentPort.on('message')`]: #worker_threads_event_message
1122[`require('worker_threads').parentPort.postMessage()`]: #worker_threads_worker_postmessage_value_transferlist
1123[`require('worker_threads').parentPort`]: #worker_threads_worker_parentport
1124[`require('worker_threads').threadId`]: #worker_threads_worker_threadid
1125[`require('worker_threads').workerData`]: #worker_threads_worker_workerdata
1126[`trace_events`]: tracing.md
1127[`v8.getHeapSnapshot()`]: v8.md#v8_v8_getheapsnapshot
1128[`vm`]: vm.md
1129[`worker.SHARE_ENV`]: #worker_threads_worker_share_env
1130[`worker.on('message')`]: #worker_threads_event_message_1
1131[`worker.postMessage()`]: #worker_threads_worker_postmessage_value_transferlist
1132[`worker.terminate()`]: #worker_threads_worker_terminate
1133[`worker.threadId`]: #worker_threads_worker_threadid_1
1134[async-resource-worker-pool]: async_hooks.md#async-resource-worker-pool
1135[browser `MessagePort`]: https://developer.mozilla.org/en-US/docs/Web/API/MessagePort
1136[child processes]: child_process.md
1137[contextified]: vm.md#vm_what_does_it_mean_to_contextify_an_object
1138[v8.serdes]: v8.md#v8_serialization_api
1139