Top-Level Await Error with Vite and Three.js: 'Top-level await is not available in the configured target environment

I am currently experimenting with the WebGPU in Three.js using Vite as my module bundler. However, I’ve encountered an issue with top-level await in my project. Below is the snippet of code that is causing the problem:

import WebGPU from 'three/examples/jsm/capabilities/WebGPU.js';
import WebGPURenderer from 'three/examples/jsm/renderers/webgpu/WebGPURenderer.js';

await new Promise((resolve) => setTimeout(resolve, 1000));

if (WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false) {
  document.body.appendChild(WebGPU.getErrorMessage());
  throw new Error('No WebGPU or WebGL2 support');
}

When I run this code, I receive the following error message:

X [ERROR] Top-level await is not available in the configured target environment ("chrome87", "edge88", "es2020", "firefox78", "safari14" + 2 overrides)
    node_modules/three/examples/jsm/capabilities/WebGPU.js:14:15:
      14 │   isAvailable = await navigator.gpu.requestAdapter();

The first await in my code works as expected, but it seems the await inside the WebGPU.js module is causing issues. I am puzzled why the first await can run but the second one in the module cannot. Could this be a configuration issue with Vite or something specific about how Three.js handles these modules?

I would appreciate any insights or suggestions on how to resolve this issue. Thank you!

  • My tsconfig.json is set with "target": "ESNext".

I remember that issue. Here is my solution. I think it will help you

1 Like

Ah, thank you so much! But I’m still curious why the await I wrote myself executes normally, whereas the “top-level await” in the imported module throws an error?

Unfortunately, I can’t tell you exactly how vite works because I don’t know.

But you don’t need that anymore.

await new Promise((resolve) => setTimeout(resolve, 1000));

if (WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false) {
  document.body.appendChild(WebGPU.getErrorMessage());
  throw new Error('No WebGPU or WebGL2 support');
}

there is also one more

await.renderer.init();

I recommend using this in your app init. This ensures that the renderer is ready before everything else is carried out.

1 Like

Okay, thanks. But, the await I wrote myself was just to test if it could run.

I think this is because your await does not contain any dependencies and can therefore be executed. But vite won’t care because it has no influence on the vite configuration. Your await is not a top level await for vite but a top level await in your app and vite must already be running for that. But vite needs its own top level await for this and you can’t implement that in the app that vite is supposed to run.

So Vite can already be running and your await can run. But since the top level await is not available in vite itself, which is necessary for webgpu, webgpu cannot be executed. But since webgpu is not necessary for your await, this can be done. But that’s just speculation on my part.

1 Like