Skip to content

Conversation

@korywka
Copy link

@korywka korywka commented Sep 17, 2025

Issue: #1372

The IS_WEBWORKER_ENV is true for Deno Worker runtime:

const IS_WEBWORKER_ENV = typeof self !== "undefined" && (['DedicatedWorkerGlobalScope', 'ServiceWorkerGlobalScope', 'SharedWorkerGlobalScope'].includes(self.constructor?.name));

So it is not reliable condition to check for HTML/Offscreen-Canvas API usage.

One way to fix it is to go from env-based conditions to feature-based.

If we add Deno condition to exclude Canvas API, it would work for now, but I think it will be broken for Node Workers (nodejs/node#43583) and Bun Web Workers.

Please note that this PR has been tested only with Deno, not other environments. It should be tested further, closed, or used as a starting point.

@xenova xenova requested a review from nico-martin October 26, 2025 23:03
@xenova
Copy link
Collaborator

xenova commented Oct 26, 2025

Thanks for the PR! This mostly looks good to me. pinging @nico-martin for another review :)

I tried with bun workers, but the existing code seems to work for that. Sounds like Deno has this issue, which your PR aims to fix. If you can provide some reproduction that makes it fail for Deno, I can test that in Bun.

Update: Bun seems to not use a name (i.e., Object) for the webworker environment, meaning the check for is web worker is always false.

Also, when both sharp and canvas is available, I'm not sure what we should default to, but I think sharp would be more performant. Open to suggestions here.

@nico-martin
Copy link
Collaborator

nico-martin commented Oct 27, 2025

I like the idea of going from runtime-detection to feature-detection.
However I was not able to reproduce the error you described:

// index.ts
const worker = new Worker(new URL("./worker.ts", import.meta.url).href);

await new Promise((resolve, reject) => {
  worker.postMessage("hello");

  worker.onmessage = (event) => {
    console.log("message received in main", event.data);
    resolve(event.data);
  };

  worker.onerror = (error) => {
    console.error("Worker error:", error);
    reject(error);
  };
});

console.log("Worker completed");
worker.terminate();

export {};
// worker.ts
import { pipeline } from "@huggingface/transformers";

declare var self: Worker;

self.onmessage = async (event: MessageEvent) => {
  console.log("message received in worker", event.data);
  const segmenter = await pipeline("background-removal", "Xenova/modnet");
  const url =
    "https://huggingface.co/datasets/Xenova/transformers.js-docs/resolve/main/portrait-of-woman_small.jpg";
  const output = await segmenter(url);
  postMessage(output);
};

I then added a console.log in transformers.js to see what IS_WEBWORKER_ENV is set to. Turns out it's false, as expected.

@korywka, could you send me an example where I can reproduce the error? Or have I misunderstood the problem?

@korywka
Copy link
Author

korywka commented Oct 27, 2025

@nico-martin Hello. Yep, I gave the link in the linked issue: #1372 (comment)

@nico-martin
Copy link
Collaborator

Thanks!
I have been able to reproduce the error with bun and verified your fix. I also tested your changes with the example above:
✅ Node v22.17.1
✅ Deno 2.2.6
✅ Bun 1.2.22
✅ Browser (Chrome 141)

lgtm!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants