Worker Threads allow Node.js to execute JavaScript in additional threads. They are especially useful for CPU-intensive tasks that would otherwise block the main JavaScript thread.
Node.js normally executes JavaScript on a single main thread.
Long-running calculations can block that thread and delay other
callbacks. The built-in worker_threads module allows
you to move suitable calculations to worker threads.
Worker Threads are useful for:
Main Thread
|
| Starts a worker
v
Worker Thread
|
| Performs CPU-intensive work
v
Sends result back to Main Thread
The main thread can continue handling other JavaScript work while the worker performs its calculation.
The worker_threads module is built into Node.js.
You do not need to install an additional npm package.
const { Worker, isMainThread } = require("worker_threads");
console.log("Main thread:", isMainThread);
Main thread: true
The isMainThread property is true when the
code is running on the main thread and false inside a worker.
A worker can execute a separate JavaScript file. In this example, the main file starts a worker and receives a message from it.
const { parentPort } = require("worker_threads");
parentPort.postMessage("Hello from Worker Thread!");
const { Worker } = require("worker_threads");
const worker = new Worker("./worker.js");
worker.on("message", function(message) {
console.log(message);
});
worker.on("error", function(error) {
console.log("Worker error:", error.message);
});
worker.on("exit", function(code) {
console.log("Worker stopped with code:", code);
});
Hello from Worker Thread!
Worker stopped with code: 0
Save both files in the same directory and run
node main.js.
You can pass data to a worker using the workerData
option. The worker receives the supplied data through the
workerData property.
Create worker.js:
const { parentPort, workerData } = require("worker_threads");
const result = workerData * workerData;
parentPort.postMessage(result);
Create main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./worker.js", {
workerData: 5
});
worker.on("message", function(result) {
console.log("Square:", result);
});
worker.on("error", function(error) {
console.log("Error:", error.message);
});
Square: 25
A worker can send messages to the main thread using
parentPort.postMessage(). The main thread can send
messages back using worker.postMessage().
Create worker.js:
const { parentPort } = require("worker_threads");
parentPort.on("message", function(number) {
parentPort.postMessage(number * 2);
});
Create main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./worker.js");
worker.on("message", function(result) {
console.log("Result:", result);
worker.terminate();
});
worker.on("error", function(error) {
console.log("Error:", error.message);
});
worker.postMessage(10);
Result: 20
The main thread sends 10 to the worker, and the worker returns 20. The main thread then terminates the worker.
Worker Threads are most useful when calculations take significant CPU time. The following example calculates the sum of numbers from 1 to a supplied limit in a separate worker.
Create sumWorker.js:
const { parentPort, workerData } = require("worker_threads");
let sum = 0;
for (let i = 1; i <= workerData; i++) {
sum += i;
}
parentPort.postMessage(sum);
Create main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./sumWorker.js", {
workerData: 1000000
});
worker.on("message", function(result) {
console.log("Sum:", result);
});
worker.on("error", function(error) {
console.log("Error:", error.message);
});
Sum: 500000500000
The worker performs the calculation and sends the final result to the main thread.
Workers can fail because of exceptions or other runtime problems.
Use the worker's error event to handle uncaught
errors in the worker.
Create errorWorker.js:
throw new Error("Something went wrong inside the worker");
Create main.js:
const { Worker } = require("worker_threads");
const worker = new Worker("./errorWorker.js");
worker.on("error", function(error) {
console.log("Worker failed:", error.message);
});
worker.on("exit", function(code) {
console.log("Worker exited with code:", code);
});
Worker failed: Something went wrong inside the worker
Worker exited with code: 1
An uncaught exception causes the worker to emit an error and exit with a nonzero code.
| Feature | Worker Threads | Child Processes |
|---|---|---|
| Execution | Separate JavaScript threads | Separate operating-system processes |
| Best suited for | CPU-intensive JavaScript | External programs and process isolation |
| Communication | Messages and shared memory options | Pipes, IPC, or other process communication |
| Memory | Can share selected memory through SharedArrayBuffer | Normally separate process memory |
| Module | worker_threads |
child_process |
Select the correct answer for each question.