Linter · Rules
n/no-top-level-await
Disallow await at the top level of a module
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
Reported:
import { connect } from "./db.js";
export const db = await connect();
for await (const row of db.rows()) {
console.log(row);
}
Not reported:
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. |
#!/usr/bin/env node
import { run } from "./cli.js";
await run(process.argv.slice(2));
#!/usr/bin/env node
import { run } from "./cli.js";
await run(process.argv.slice(2));
When not to use it
In an application, or in any module that nobody loads with require(), top-level await is harmless.