n/no-top-level-await
Disallow await at the top level of a module
Also called node/no-top-level-await
Node.js can load an ES module with require(), but not one that uses await at its top level, or one that imports a module like that. In both cases require() throws ERR_REQUIRE_ASYNC_MODULE. For a published package, that locks out everyone who still uses CommonJS.
await, for await and await using are reported when they're outside of every function.
Configure#
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"n/no-top-level-await" = "error" # or "warn"Every option, set to its default:
bunfig.toml
[lint.rules]
"n/no-top-level-await" = ["error", {
ignoreBin = false,
}]Examples#
example.js2 problems
import { connect } from "./db.js";
export const db = await connect()Top-level await prevents this module from being loaded with require(esm).;
for await (const row of db.rows()) {Top-level await prevents this module from being loaded with require(esm).
console.log(row);
}example.jsNo problems
import { connect } from "./db.js";
let db;
export async function getDb() {
db ??= await connect();
return db;
}Options#
| Option | Default | What it does |
|---|---|---|
ignoreBin | false | Skip files that start with #!. They're run, not imported. |
example.jswith
{ "ignoreBin": true }No problems#!/usr/bin/env node
import { run } from "./cli.js";
await run(process.argv.slice(2));example.js1 problem
#!/usr/bin/env node
import { run } from "./cli.js";
await run(process.argv.slice(2))Top-level await prevents this module from being loaded with require(esm).;When not to use it#
In an application, or in any module that nobody loads with require(), top-level await is harmless.