Skip to content
← Back to rules

node/no-top-level-await Restriction

What it does

Disallows the use of top-level await, including for await...of loops and await using declarations that are not nested inside a function.

Why is this bad?

Node.js v20.19 introduced require(esm), but ES modules with top-level await cannot be loaded with require(esm). Avoiding top-level await keeps a module loadable from both CommonJS require() and ESM import.

Examples

Examples of incorrect code for this rule:

js
const foo = await import("foo");

for await (const e of asyncIterate()) {
  // ...
}

Examples of correct code for this rule:

js
async function fn() {
  const foo = await import("foo");
}

Configuration

This rule accepts a configuration object with the following properties:

ignoreBin

type: boolean

default: false

If true, top-level await is allowed in files that start with a hashbang (#!), which marks them as executable scripts rather than importable modules.

How to use

To enable this rule using the config file or in the CLI, you can use:

json
{
  "plugins": ["node"],
  "rules": {
    "node/no-top-level-await": "error"
  }
}
ts
import { defineConfig } from "oxlint";

export default defineConfig({
  plugins: ["node"],
  rules: {
    "node/no-top-level-await": "error",
  },
});
bash
oxlint --deny node/no-top-level-await --node-plugin

Version

This rule was added in vnext.

References