Worker: Worker() constructor - Web APIs | MDN
Skip to search
Worker: Worker() constructor
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.
* Some parts of this feature may have varying levels of support.
See full compatibility
Report feedback
Note:
This feature is available in
Web Workers
, except for
Service Workers
Warning:
This script passed to the
url
element is executed.
APIs like this are known as
injection sinks
, and are potentially a vector for
cross-site scripting (XSS)
attacks.
You can mitigate this risk by having a
Content Security Policy (CSP)
that restricts the locations from which scripts can be loaded, and by always assigning
TrustedScriptURL
objects instead of strings and
enforcing trusted types
See
Security considerations
for more information.
The
Worker()
constructor creates a
Worker
object that executes the classic script or module at the specified URL.
Syntax
js
new Worker(url)
new Worker(url, options)
Parameters
url
TrustedScriptURL
object or a string representing the URL of the script or module that the worker will execute.
This must be same-origin with the caller's document, or a
blob:
or
data:
URL.
The URL is resolved relative to the current HTML page's location.
options
Optional
An object containing option properties that can be set when creating the object instance.
Available properties are as follows:
credentials
A string specifying whether the browser sends credentials when importing modules into a module worker.
The allowed values are the same as can be passed to the
fetch()
request
omit
same-origin
, or
include
The default is
same-origin
(only include credentials for same-origin requests).
This is ignored for classic workers.
name
A string specifying an identifying name for the
DedicatedWorkerGlobalScope
representing the scope of the worker, which is mainly useful for debugging purposes.
type
A string specifying the type of worker to create.
The value can be
classic
or
module
The default is
classic
Exceptions
NetworkError
DOMException
Thrown if the MIME type of the worker script is incorrect.
It
should
always be
text/javascript
(for historical reasons
other JavaScript MIME types
may be accepted).
SecurityError
DOMException
Thrown if the document is not allowed to start workers, e.g., if the URL has an invalid syntax or if the same-origin policy is violated.
SyntaxError
DOMException
Thrown if
url
cannot be parsed.
TypeError
Thrown if the
url
parameter is a string when
Trusted Types
are
enforced by a CSP
and no default policy is defined.
Description
The
Worker()
constructor creates a
Worker
object that executes the classic script or module at the specified URL.
The script must be
same-origin
with the associated document, but may itself import scripts or modules that are cross-origin (if permitted by CORS and other restrictions).
If a cross-origin worker is required, users must load it from an intermediate same-origin worker or a blob.
Module and classic workers
A classic worker is one that is constructed from a classic script, while a module worker is constructed from an
ECMASCript module
The type of worker affects the worker constructor options, how the worker script is fetched, and how it is executed.
The code below shows two ways you can construct a classic worker, and also how you specify the
type
of
"module"
to create a module worker.
In both cases the script must be same-origin with the loading document and is resolved relative to the location of the launching document.
js
// Construct a classic worker
const worker1 = new Worker("worker_classic.js");
const worker2 = new Worker("worker_classic.js", {
type: "classic",
});

// Construct a module worker
const worker3 = new Worker("worker_module.js", {
type: "module",
});
Module workers and their dependencies are loaded and executed using ECMAScript module semantics:
Dependencies are imported via static
import
statements
Fetched asynchronously using
CORS
All modules are resolved before any code is executed
Must be served with the media type
Content-Type: text/javascript
Executed in
Strict mode
Classic workers are fetched and executed as scripts:
Dependencies are imported using the
WorkerGlobalScope.importScripts()
method
Fetched synchronously in
no-cors
mode
Importing scripts or modules
Module workers can import
ECMASCript modules
using
import
statements
Modules are fetched using CORS, so cross-origin modules must be served with the
Access-Control-Allow-Origin
header in order to be loaded.
Developers can specify whether or not credentials should be sent in cross-origin imports.
Classic workers can import scripts (but not modules) using the
WorkerGlobalScope.importScripts()
method.
Unlike modules, scripts are fetched in
no-cors
mode, and can be requested cross-origin even if the server does not set the appropriate CORS headers.
Credentials are sent for same-origin imports, but are usually not sent for cross-origin requests.
In addition, if the document has a
Content Security Policy (CSP)
, it must allow the origins of imported scripts or modules.
For modules the allowed sources are specified in
worker-src
(with fallback to
script-src
and
default-src
directives), while for classic scripts the sources are specified in
script-src
(with fallback to the
default-src
directives).
data:
and
blob:
URLs
data:
URLs can be passed to the
url
parameter, but have an
opaque_origin
, which makes them cross-origin to all other origins including their owner.
Consequently, while the worker can still communicate with its owner using
postMessage()
, it's access to other external resources is highly restricted.
For example, a worker
fetch()
request would be cross-origin to its own site, and any requests to any origin must be granted by CORS.
blob:
URLs should be used instead, where possible, because the URL inherits the origin of the document that created it.
This ensures that a worker created with a
blob:
URL is same-origin with the page that created it.
Note that if you're using a
Content Security Policy (CSP)
to restrict what resources can be loaded into your worker, you will need to allow the
blob:
origin.
Bundler considerations
Bundlers such as
webpack
Vite
, and
Parcel
, recommend passing URLs that are relative to
import.meta.url
to the
Worker()
constructor.
For example:
js
const myWorker = new Worker(new URL("worker.js", import.meta.url));
This makes the path relative to the current script instead of the current HTML page, which allows the bundler to safely do optimizations like renaming (because otherwise the
worker.js
URL may point to a file not controlled by the bundler, so it cannot make any assumptions).
Security considerations
The script or module specified by the
url
argument is executed in the web worker context, and may itself import other same-origin and cross-origin scripts.
If the
url
is provided by a user, this is a possible vector for
cross-site scripting (XSS)
attacks.
While web workers do not have direct access to the owning document or window, it is still extremely risky to accept and execute arbitrary URLs from untrusted origins.
For module workers, but not classic workers, CORS will control what cross-origin resources can be requested.
A website should also control what scripts that are allowed to run using a
Content Security Policy (CSP)
with the
worker-src
directive (or a fallback to
child-src
script-src
, or
default-src
).
This can restrict scripts to those from the current origin, or a specific set of origins, or even particular files.
If you're using this property and
enforcing trusted types
(using the
require-trusted-types-for
CSP directive), you will need to always assign
TrustedScriptURL
objects instead of strings.
This ensures that the input is passed through a transformation function, which has the chance to reject or modify URLs needed by the worker before they are fetched.
Examples
For brevity, only the first example below uses trusted types.
In production your code should always use trusted types when passing data originating from users into injection sinks.
Using Trusted Types
To mitigate the risk of XSS, we should always pass
TrustedScriptURL
instances to the worker URL instead of strings.
We also need to do this if we're enforcing trusted types for other reasons and we want to allow some sources that have been permitted (by
CSP: worker-src
).
Trusted types are not yet supported on all browsers, so first we define the
trusted types tinyfill
This acts as a transparent replacement for the trusted types JavaScript API:
js
if (typeof trustedTypes === "undefined")
trustedTypes = { createPolicy: (n, rules) => rules };
Next we create a
TrustedTypePolicy
that defines a
createScriptURL()
method for transforming input strings into
TrustedScriptURL
instances.
For the purpose of this example we'll assume that we want to allow a predefined set of URLs in the
workerScriptAllowList
array and log any other scripts.
js
const workerScriptAllowList = [
// Some list of allowed URLs
];
const policy = trustedTypes.createPolicy("worker-url-policy", {
createScriptURL(input) {
if (workerScriptAllowList.includes(input)) {
return input; // allow the script
console.log(`Script not in workerScriptAllowList: ${input}`);
return ""; // Block the script
},
});
Next we use our
policy
object to create a
trustedScriptURL
object from a potentially unsafe input string and pass this to the worker.
js
// The potentially malicious worker URL
// We won't be including untrustedScript in our workerScriptAllowList array
const untrustedScriptURL = "https://evil.example.com/naughty.js";

// Create a TrustedScriptURL instance using the policy
const trustedScriptURL = policy.createScriptURL(untrustedScriptURL);

// Construct the worker with the trusted URL
const myWorker = new Worker(trustedScriptURL);
Creating a classic worker
The following code snippet shows creation of a classic
Worker
object using the
Worker()
constructor, and subsequent usage of the object:
js
const myWorker = new Worker("worker.js");
const first = document.querySelector("input#number1");

first.onchange = () => {
myWorker.postMessage(first.value);
console.log("Message posted to worker");
};
For a full example, see our
Basic dedicated worker example
run dedicated worker
).
Loading a cross-origin module worker from a blob
This example shows a method that can fetch and load a cross-origin module worker script and then load it into your worker as a blob (a classic script could be loaded in the same way):
js
async function loadWorker() {
const response = await fetch("https://other_origin.com/worker.js");
const script = await response.text();

// Create a blob that contains the fetched script, and then create a URL from that blob
const blob = new Blob([script], { type: "application/javascript" });
const workerUrl = URL.createObjectURL(blob);

try {
const worker = new Worker(workerUrl, { type: "module" });
} catch (e) {
console.error(`Cross-origin worker module failed to load: ${e}`);
loadWorker();
The initial fetch is made with CORS, and so the
other_origin.com
response will need to include the
Access-Control-Allow-Origin
header as shown:
http
Access-Control-Allow-Origin "https://my_origin.com"
In addition, if you're using a CSP you will need to allow the
blob:
origin for
worker-src
so that it can be loaded into the document:
http
Content-Security-Policy worker-src 'self' https://other_origin.com blob:
Specifications
Specification
HTML
# dom-worker-dev
Browser compatibility
See also
Worker
Trusted Types API
Help improve MDN
Learn how to contribute
This page was last modified on
Apr 2, 2026
by
MDN contributors
View this page on GitHub
Report a problem with this content