This rule raises an issue when async operations are wrapped in immediately invoked function expressions, promise chains, or async functions that are called immediately at the top level.

Why is this an issue?

JavaScript’s top-level await feature allows you to use await directly at the module level without wrapping async operations in functions. This makes code cleaner and more readable.

When you wrap async operations in immediately invoked function expressions (IIFEs) or create async functions just to call them immediately, you add unnecessary boilerplate code. This pattern was common before top-level await was available, but is no longer needed in modern JavaScript environments.

Using wrapper patterns can also make error handling more complex and may lead to unhandled promise rejections if not properly managed. Top-level await provides a more straightforward approach to handling async operations at the module level.

What is the potential impact?

Using wrapper patterns instead of top-level await reduces code readability and maintainability. It adds unnecessary complexity and boilerplate code that makes the intent less clear. In some cases, improper error handling in wrapper patterns can lead to unhandled promise rejections.

How to fix?

Replace immediately invoked async function expressions with top-level await.

Non-compliant code example

(async () => {
  try {
    await run();
  } catch (error) {
    console.error(error);
    process.exit(1);
  }
})(); // Noncompliant

Compliant code example

try {
  await run();
} catch (error) {
  console.error(error);
  process.exit(1);
}

Documentation