Worker: postMessage() method

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Note: This feature is available in Web Workers, except for Service Workers.

The postMessage() method of the Worker interface sends a message to the worker. The first parameter is the data to send to the worker. The data may be any JavaScript object that can be handled by the structured clone algorithm.

The Worker postMessage() method delegates to the MessagePort postMessage() method, which adds a task on the event loop corresponding to the receiving MessagePort.

The Worker can send back information to the thread that spawned it using the DedicatedWorkerGlobalScope.postMessage method.

Syntax

js
postMessage(message)
postMessage(message, transfer)
postMessage(message, options)

Parameters

message

The object to deliver to the worker; this will be in the data field in the event delivered to the message event. This may be any value or JavaScript object handled by the structured clone algorithm, which includes cyclical references.

The message parameter is mandatory. If the data to be passed to the worker is unimportant, null or undefined must be passed explicitly.

transfer Optional

An optional array of transferable objects to transfer ownership of. The ownership of these objects is given to the destination side and they are no longer usable on the sending side. These transferable objects are not automatically sent; they must either be contained in the message or be accessible to the recipient via other means, such as MessagePort via MessageEvent.ports.

options Optional

An optional object containing the following properties:

transfer Optional

Has the same meaning as the transfer parameter.

Return value

None (undefined).

Examples

The following code snippet shows the creation of a Worker object using the Worker() constructor. When either of two form inputs (first and second) have their values changed, change events invoke postMessage() to send the value of both inputs to the current worker.

js
const myWorker = new Worker("worker.js");

[first, second].forEach((input) => {
  input.onchange = () => {
    myWorker.postMessage([first.value, second.value]);
    console.log("Message posted to worker");
  };
});

For a full example, see our simple worker example (run example).

Note: postMessage() can only send a single object at once. As seen above, if you want to pass multiple values you can send an array.

Transfer Example

This minimum example has main create an ArrayBuffer and transfer it to myWorker, then has myWorker transfer it back to main, with the size logged at each step.

main.js code

js
// create worker
const myWorker = new Worker("myWorker.js");

// listen for myWorker to transfer the buffer back to main
myWorker.addEventListener("message", (msg) => {
  console.log("message from worker received in main:", msg);

  const bufTransferredBackFromWorker = msg.data;

  console.log(
    "buf.byteLength in main AFTER transfer back from worker:",
    bufTransferredBackFromWorker.byteLength,
  );
});

// create the buffer
const myBuf = new ArrayBuffer(8);

console.log(
  "buf.byteLength in main BEFORE transfer to worker:",
  myBuf.byteLength,
);

// send myBuf to myWorker and transfer the underlying ArrayBuffer
myWorker.postMessage(myBuf, [myBuf]);

console.log(
  "buf.byteLength in main AFTER transfer to worker:",
  myBuf.byteLength,
);

myWorker.js code

js
// listen for main to transfer the buffer to myWorker
self.onmessage = (msg) => {
  console.log("message from main received in worker:", msg);

  const bufTransferredFromMain = msg.data;

  console.log(
    "buf.byteLength in worker BEFORE transfer back to main:",
    bufTransferredFromMain.byteLength,
  );

  // send buf back to main and transfer the underlying ArrayBuffer
  self.postMessage(bufTransferredFromMain, [bufTransferredFromMain]);

  console.log(
    "buf.byteLength in worker AFTER transfer back to main:",
    bufTransferredFromMain.byteLength,
  );
};

Output logged

bash
buf.byteLength in main BEFORE transfer to worker:        8                     main.js:19
buf.byteLength in main AFTER transfer to worker:         0                     main.js:27

message from main received in worker:                    MessageEvent { ... }  myWorker.js:3
buf.byteLength in worker BEFORE transfer back to main:   8                     myWorker.js:7
buf.byteLength in worker AFTER transfer back to main:    0                     myWorker.js:15

message from worker received in main:                    MessageEvent { ... }  main.js:6
buf.byteLength in main AFTER transfer back from worker:  8                     main.js:10

byteLength goes to 0 after the ArrayBuffer is transferred. For a more sophisticated full working example of ArrayBuffer transfer, see this Firefox demo add-on: GitHub :: ChromeWorker - demo-transfer-arraybuffer

Specifications

Specification
HTML
# dom-worker-postmessage-dev

Browser compatibility

desktop mobile server
Chrome
Edge
Firefox
Opera
Safari
Chrome Android
Firefox for Android
Opera Android
Safari on iOS
Samsung Internet
WebView Android
WebView on iOS
Bun
Deno
Node.js
postMessage
Chrome – Full support
Chrome 2 (Release date: 2009-05-21)
footnote Full support
Edge – Full support
Edge 12 (Release date: 2015-07-29)
footnote Full support
Firefox – Full support
Firefox 3.5 (Release date: 2009-06-30)
footnote Full support
Opera – Full support
Opera 10.6 (Release date: 2010-07-01)
footnote Full support
Safari – Full support
Safari 4 (Release date: 2009-06-08)
footnote Full support
Chrome Android – Full support
Chrome Android 18 (Release date: 2012-06-27)
footnote Full support
Firefox for Android – Full support
Firefox for Android 4 (Release date: 2011-03-29)
footnote Full support
Opera Android – Full support
Opera Android 11 (Release date: 2011-03-22)
footnote Full support
Safari on iOS – Full support
Safari on iOS 5 (Release date: 2011-10-12)
footnote Full support
Samsung Internet – Full support
Samsung Internet 1 (Release date: 2013-04-27)
footnote Full support
WebView Android – Full support
WebView Android 4.4 (Release date: 2013-12-09)
footnote Full support
WebView on iOS – Full support
WebView on iOS 5 (Release date: 2011-10-12)
footnote Full support
Bun – Full support
Bun 1 (Release date: 2023-09-08)
footnote Full support
Deno – Partial support
Deno 1 – 1.9 (Release date: 2020-05-13)
footnote Partial support
footnote Data passed in the message parameter is serialized with JSON, not the structured clone algorithm.
footnote The transfer parameter is not supported, and results in an error being thrown.
Deno – Partial support
Deno 1.10 – 1.11 (Release date: 2021-05-11)
footnote Partial support
footnote The message parameter does not support SharedArrayBuffer.
footnote The transfer parameter is not supported, and results in an error being thrown.
Deno – Partial support
Deno 1.12 – 1.13 (Release date: 2021-07-13)
footnote Partial support
footnote The message parameter does not support cloning Blob values.
footnote The transfer parameter does not accept ArrayBuffer items. Passing an ArrayBuffer results in an error being thrown.
Deno – Full support
Deno 1.14 (Release date: 2021-09-14)
footnote
footnote The message parameter does not support cloning Blob values.
Node.js – Partial support
Node.js 11.7 (Release date: 2019-01-18)
footnote Partial support
footnote Only accepts an array of transfer objects as the second parameter, not an options object with a transfer property.
footnote Only supports transferring ArrayBuffer and MessagePort objects.
options.includeUserActivation parameter
Non-standard
Chrome – Full support
Chrome 72 (Release date: 2019-01-29)
footnote Full support
Edge – Full support
Edge 79 (Release date: 2020-01-15)
footnote Full support
Firefox – No support
Firefox
footnote No support
Opera – Full support
Opera 60 (Release date: 2019-04-09)
footnote Full support
Safari – No support
Safari
footnote No support
Chrome Android – Full support
Chrome Android 72 (Release date: 2019-01-29)
footnote Full support
Firefox for Android – No support
Firefox for Android
footnote No support
Opera Android – Full support
Opera Android 51 (Release date: 2019-03-21)
footnote Full support
Safari on iOS – No support
Safari on iOS
footnote No support
Samsung Internet – Full support
Samsung Internet 11 (Release date: 2019-12-05)
footnote Full support
WebView Android – Full support
WebView Android 72 (Release date: 2019-01-29)
footnote Full support
WebView on iOS – No support
WebView on iOS
footnote No support
Bun – No support
Bun
footnote No support
Deno – No support
Deno
footnote No support
Node.js – No support
Node.js
footnote No support

Legend

Tip: you can click/tap on a cell for more information.

Full support
Full support
Partial support
Partial support
No support
No support
Non-standard. Check cross-browser support before using.
See implementation notes.
Has more compatibility info.

See also

  • The Worker interface it belongs to.