Workers

Deno supports Web Worker API.

Workers can be used to run code on multiple threads. Each instance of Worker is run on a separate thread, dedicated only to that worker.

Currently Deno supports only module type workers; thus it’s essential to pass the type: "module" option when creating a new worker.

Relative module specifiers are not supported at the moment. You can instead use the URL contructor and import.meta.url to easily create a specifier for some nearby script.

  1. // Good
  2. new Worker(new URL("worker.js", import.meta.url).href, { type: "module" });
  3. // Bad
  4. new Worker(new URL("worker.js", import.meta.url).href);
  5. new Worker(new URL("worker.js", import.meta.url).href, { type: "classic" });
  6. new Worker("./worker.js", { type: "module" });

Permissions

Creating a new Worker instance is similar to a dynamic import; therefore Deno requires appropriate permission for this action.

For workers using local modules; --allow-read permission is required:

main.ts

  1. new Worker(new URL("worker.ts", import.meta.url).href, { type: "module" });

worker.ts

  1. console.log("hello world");
  2. self.close();
  1. $ deno run main.ts
  2. error: Uncaught PermissionDenied: read access to "./worker.ts", run again with the --allow-read flag
  3. $ deno run --allow-read main.ts
  4. hello world

For workers using remote modules; --allow-net permission is required:

main.ts

  1. new Worker("https://example.com/worker.ts", { type: "module" });

worker.ts (at https://example.com/worker.ts)

  1. console.log("hello world");
  2. self.close();
  1. $ deno run main.ts
  2. error: Uncaught PermissionDenied: net access to "https://example.com/worker.ts", run again with the --allow-net flag
  3. $ deno run --allow-net main.ts
  4. hello world

Using Deno in worker

This is an unstable Deno feature. Learn more about unstable features.

By default the Deno namespace is not available in worker scope.

To add the Deno namespace pass deno: true option when creating new worker:

main.js

  1. const worker = new Worker(new URL("worker.js", import.meta.url).href, {
  2. type: "module",
  3. deno: true,
  4. });
  5. worker.postMessage({ filename: "./log.txt" });

worker.js

  1. self.onmessage = async (e) => {
  2. const { filename } = e.data;
  3. const text = await Deno.readTextFile(filename);
  4. console.log(text);
  5. self.close();
  6. };

log.txt

  1. hello world
  1. $ deno run --allow-read --unstable main.js
  2. hello world

When the Deno namespace is available in worker scope, the worker inherits its parent process’ permissions (the ones specified using --allow-* flags).

We intend to make permissions configurable for workers.