JavaScript Worker Constructor

Beginner
⏱️ 14 min read
📚 Updated: Jul 2026
🎯 5 Examples
🚀 5 Try-it labs
Baseline Widely available
Web API constructor

What You’ll Learn

The Worker() constructor creates a dedicated Worker that runs a classic script or module at a URL on a background thread. Learn url rules, type / name options, blob URLs for demos, and messaging with postMessage—with five examples and try-it labs.

01

Create

new Worker()

02

URL

same-origin / blob

03

Type

classic | module

04

Name

debug label

05

Talk

postMessage

06

Status

Baseline widely

Introduction

Heavy work on the main thread can freeze clicks and scrolling. A dedicated worker runs JavaScript in parallel. You start it with new Worker(url), send data with worker.postMessage(...), and listen with worker.onmessage (or addEventListener("message")).

The worker script must usually be same-origin with your page (or a blob: / data: URL). In these tutorials we often build a small script as a Blob so the demo works in one HTML file.

💡
Beginner tip

Workers cannot touch the DOM. They talk to the page with messages. Think “mailbox,” not “shared variables.”

⚠️
Security note

The URL you pass is executed. Never pass untrusted user URLs into new Worker() without strict allow-lists, CSP (worker-src), and preferably Trusted Types (TrustedScriptURL).

Understanding the Worker() Constructor

A Web API constructor that returns a Worker object running the script or module at url.

  • url — string or TrustedScriptURL; same-origin, or blob: / data:.
  • options.type"classic" (default) or "module".
  • options.name — debug name for the worker scope.
  • options.credentials — for module workers: omit, same-origin (default), or include.
  • Baseline Widely available on MDN (since July 2015); some parts may vary. Available in Web Workers except Service Workers.

📝 Syntax

JavaScript
new Worker(url)
new Worker(url, options)

Parameters

ParameterMeaning
urlScript/module URL (TrustedScriptURL or string)
options.type"classic" or "module" (default classic)
options.nameIdentifying name (handy for debugging)
options.credentialsModule import credentials; ignored for classic

Return value

A new Worker object.

Classic worker (file)

JavaScript
const myWorker = new Worker("worker.js");
// or explicitly:
const classic = new Worker("worker.js", { type: "classic" });

Module worker

JavaScript
const moduleWorker = new Worker("worker_module.js", {
  type: "module"
});

Blob URL pattern (single-page demos)

JavaScript
const code = `
  self.onmessage = (e) => {
    self.postMessage(e.data);
  };
`;
const blob = new Blob([code], { type: "application/javascript" });
const url = URL.createObjectURL(blob);
const worker = new Worker(url);

⚡ Quick Reference

GoalCode / note
Start classicnew Worker("worker.js")
Start modulenew Worker("w.js", { type: "module" })
Name for DevTools{ name: "math-worker" }
Send / receiveworker.postMessage(data) / onmessage
Stopworker.terminate()
MDN statusBaseline Widely available (since July 2015)

🔍 At a Glance

Four facts to remember about Worker().

Creates
Worker

Background thread

Needs
url

Same-origin / blob

Default
classic

type option

Baseline
widely

Since Jul 2015

Examples Gallery

Examples follow MDN Worker: Worker(). Labs use blob URLs so they run in one HTML document.

📚 Getting Started

Create a worker and exchange a simple message.

Example 1 — Create a Classic Worker (Blob URL)

Build worker source in a Blob, then new Worker(url).

JavaScript
const code = `
  self.onmessage = (e) => self.postMessage("echo: " + e.data);
`;
const url = URL.createObjectURL(
  new Blob([code], { type: "application/javascript" })
);
const worker = new Worker(url);

worker.onmessage = (e) => console.log(e.data);
worker.postMessage("hello");
Try It Yourself

How It Works

Same idea as new Worker("worker.js"), but the script lives in a blob for demos.

Example 2 — name Option for Debugging

Pass { name: "..." }; the worker can read self.name.

JavaScript
const code = `self.onmessage = () => self.postMessage(self.name);`;
const url = URL.createObjectURL(
  new Blob([code], { type: "application/javascript" })
);
const worker = new Worker(url, { name: "math-worker" });

worker.onmessage = (e) => console.log(e.data); // "math-worker"
worker.postMessage(null);
Try It Yourself

How It Works

MDN notes the name identifies the DedicatedWorkerGlobalScope—mainly for debugging.

📈 Work, Errors & Cleanup

Offload a calculation, handle errors, and terminate when done.

Example 3 — Compute Off the Main Thread

Worker doubles a number and replies.

JavaScript
const code = `
  self.onmessage = (e) => {
    self.postMessage(Number(e.data) * 2);
  };
`;
const worker = new Worker(
  URL.createObjectURL(new Blob([code], { type: "application/javascript" }))
);

worker.onmessage = (e) => console.log("result =", e.data);
worker.postMessage(21);
Try It Yourself

How It Works

Real apps use this pattern for parsing, crypto, image work, and other CPU-heavy tasks.

Example 4 — Listen for Worker Errors

Use onerror when the worker script throws.

JavaScript
const code = `throw new Error("boom");`;
const worker = new Worker(
  URL.createObjectURL(new Blob([code], { type: "application/javascript" }))
);

worker.onerror = (err) => {
  console.log("worker error:", err.message);
  err.preventDefault(); // stop the browser default error UI where supported
};
Try It Yourself

How It Works

Always attach error handlers in production so a bad worker does not fail silently.

Example 5 — terminate() When Finished

Stop the worker and revoke the blob URL to free resources.

JavaScript
const url = URL.createObjectURL(
  new Blob([`self.onmessage = (e) => self.postMessage(e.data);`], {
    type: "application/javascript"
  })
);
const worker = new Worker(url);

worker.onmessage = (e) => {
  console.log(e.data);
  worker.terminate();
  URL.revokeObjectURL(url);
};
worker.postMessage("done");
Try It Yourself

How It Works

terminate() stops the worker immediately from the main thread side.

🚀 Common Use Cases

  • Heavy math, sorting, or parsing without freezing the UI.
  • Image / audio processing in the background.
  • Keeping network + decode work off the main thread.
  • Teaching concurrency with a simple message API.
  • Bundler apps: new Worker(new URL("worker.js", import.meta.url)).

🔧 How It Works

1

Resolve URL

Browser resolves the worker script relative to the page (or uses blob/data).

URL
2

Fetch & start

Classic or module rules apply; script runs in a dedicated worker scope.

Start
3

Message channel

Main thread and worker exchange data with postMessage / onmessage.

Talk
4

UI stays responsive

Heavy work happens off the main thread until you terminate or the worker exits.

📝 Notes

  • MDN: Baseline Widely available (since July 2015) — no Deprecated / Experimental / Non-standard banner. Some parts may vary.
  • Available in Web Workers except Service Workers.
  • Script URL is an injection sink—treat untrusted URLs carefully; prefer CSP + Trusted Types.
  • Prefer blob: over data: when you generate worker source (same-origin inheritance).
  • Related learning: JavaScript hub, addEventListener(), Event().

Universal Browser Support

Worker() is marked Baseline Widely available on MDN (since July 2015). Some options (for example module workers) may have varying support. Logos use the shared browser-image-sprite.png sprite from this project.

Baseline · Widely available

Worker()

Creates a dedicated Worker that runs a classic script or module at the given URL.

Universal Widely available
Google Chrome Full support · Desktop & Mobile
Full support
Mozilla Firefox Full support · Desktop & Mobile
Full support
Apple Safari Full support · macOS & iOS
Full support
Microsoft Edge Full support · Chromium
Full support
Opera Full support · Modern versions
Full support
Internet Explorer Workers supported in IE10+ (prefer modern browsers)
Legacy
Worker() Excellent

Bottom line: Use new Worker(url) for background scripts; start with classic + blob demos, then add module workers when you need ES imports.

Conclusion

new Worker(url, options) starts a dedicated background script. Keep URLs same-origin (or blob), choose classic vs module deliberately, and talk to the worker with messages—never by sharing the DOM.

Continue with postMessage(), addEventListener(), or Event().

💡 Best Practices

✅ Do

  • Use fixed same-origin worker files in apps
  • Prefer blob URLs over data URLs for generated scripts
  • Set name when debugging multiple workers
  • Handle onerror / message errors
  • Revoke blob URLs after terminate()

❌ Don’t

  • Pass untrusted URLs into new Worker()
  • Expect DOM access inside the worker
  • Forget CORS when loading cross-origin module scripts
  • Leave unused workers running forever
  • Skip CSP worker-src on production sites

Key Takeaways

Knowledge Unlocked

Five things to remember about Worker()

Background scripts started with a URL.

5
Core concepts
🔗02

URL

same-origin / blob

Input
📦03

classic|module

type option

Mode
💬04

Messages

postMessage

Talk
🎯05

Baseline

since Jul 2015

Status

❓ Frequently Asked Questions

new Worker(url, options) creates a dedicated Worker that runs a classic script or module at the given URL on a background thread, separate from the main page UI thread.
No. MDN marks the Worker() constructor as Baseline Widely available (since July 2015). It is not Deprecated, Experimental, or Non-standard. Some options may have varying support. It is available in Web Workers except Service Workers.
A same-origin script URL (resolved relative to the HTML page), or a blob: or data: URL. Cross-origin worker scripts usually need an intermediate same-origin worker or a blob loaded after a CORS fetch.
type: "classic" (default) runs a classic script and can use importScripts(). type: "module" runs an ES module with import, CORS fetching, and strict mode.
In a single HTML file you often have no separate worker.js. Building a Blob of JavaScript and passing URL.createObjectURL(blob) creates a same-origin worker URL you can start immediately.
Yes if the URL comes from untrusted input—the script is executed (an injection sink / XSS risk). Prefer fixed same-origin scripts, CSP worker-src, and TrustedScriptURL when enforcing Trusted Types.
Did you know?

Bundlers like webpack, Vite, and Parcel often recommend new Worker(new URL("worker.js", import.meta.url)) so the worker path stays relative to the script, not the HTML page—safer for renaming and packaging.

Next: postMessage()

Send structured-clone data (and transfers) to your worker.

postMessage() →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

5 people found this page helpful