Linter · Rules
unicorn/prefer-top-level-await
Require top-level await instead of promise chains and async wrappers at the top of a module
A module can use await outside of a function. An async wrapper or a .then() chain at the top level is more code for the same work. Modules that import the file don't wait for it, and a rejection becomes an unhandled rejection instead of a failed import.
The rule reports three things outside of functions and classes:
- a call to
.then(),.catch()or.finally()that isn't awaited - an async function that's called right where it's written
- a call to an async function declared in the file, if that call is the only place it's used
Configure
Off by default. To turn it on:
bunfig.toml
[lint.rules]
"unicorn/prefer-top-level-await" = "error" # or "warn"
Examples
Reported:
(async () => {
await connect();
})();
loadConfig().then(config => start(config));
async function main() {
await migrate();
}
main();
Not reported:
await connect();
const config = await loadConfig();
start(config);
await migrate();
const [users, posts] = await Promise.all([loadUsers().catch(() => []), loadPosts()]);
When not to use it
Top-level await is a syntax error in CommonJS, and the rule doesn't look at how a file is loaded. It reports this in main.cjs too:
loadConfig().then(config => start(config));
Turn the rule off for files that are loaded as CommonJS.