{"record":{"id":"c5f073b41c983223","repo":"oxc-project/oxc","slug":"prefer-top-level-await-over-using-an-async-iife","errorCode":null,"errorMessage":"Prefer top-level await over using an async IIFE.","messagePattern":"Prefer top-level await over using an async IIFE\\.","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"warning","filePath":"crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs","lineNumber":19,"sourceCode":"use oxc_ast::{\n    AstKind,\n    ast::{Expression, VariableDeclarationKind},\n};\nuse oxc_diagnostics::OxcDiagnostic;\nuse oxc_macros::declare_oxc_lint;\nuse oxc_span::{GetSpan, Span};\n\nuse crate::{\n    AstNode, ast_util::is_method_call, ast_util::variable_declaration_kind, context::LintContext,\n    rule::Rule,\n};\n\nfn prefer_top_level_await_over_promise_chain_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prefer top-level await over using a promise chain.\").with_label(span)\n}\n\nfn prefer_top_level_await_over_async_iife_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prefer top-level await over using an async IIFE.\").with_label(span)\n}\n\nfn prefer_top_level_await_over_async_function_call_diagnostic(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Prefer top-level await over an async function call.\")\n        .with_help(\"Add `await` before the function call.\")\n        .with_label(span)\n}\n\n#[derive(Debug, Default, Clone)]\npub struct PreferTopLevelAwait;\n\ndeclare_oxc_lint!(\n    /// ### What it does\n    ///\n    /// Prefer top-level await over top-level promises and async function calls.\n    ///\n    /// ### Why is this bad?\n    ///","sourceCodeStart":1,"sourceCodeEnd":37,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/unicorn/prefer_top_level_await.rs#L1-L37","documentation":"This is the async-IIFE diagnostic of oxlint's `unicorn/prefer-top-level-await`. It flags the historical pattern `(async () => { ... })()` (or `(async function () { ... })()`) used only to get `await` at module top level, and recommends top-level `await` in ES modules instead, which removes the wrapper and its scoping/error-handling quirks.","triggerScenarios":"A top-level expression statement that is an immediately-invoked async arrow or function expression in a module; the rule pairs this with the promise-chain and async-call diagnostics from the same file to cover the three common pre-top-level-await idioms.","commonSituations":"Legacy bootstrap code like `(async () => { await init(); await migrate(); })().catch(console.error);` written before Node 14.8/bundler TLA support; after migrating the package to ESM these wrappers become dead weight and obscure stack traces.","solutions":["Unwrap the IIFE and `await` its body directly at module top level; move the `.catch` into a `try { ... } catch` block or keep a top-level `await promise.catch(...)` if you need to swallow errors.","Confirm the file is ESM and the runtime supports top-level await before applying.","If the IIFE exists to create a scope (name isolation), keep it and disable the rule for the line, or use a block `{ ... }` plus `await`."],"exampleFix":"// before\n(async () => {\n  await init();\n  await migrate();\n})();\n\n// after\nawait init();\nawait migrate();","handlingStrategy":"validation","validationCode":"// In ESM, drop the async IIFE wrapper\nawait init();\nawait migrate();\n// CI: npx oxlint --deny-warn unicorn/prefer-top-level-await src/","typeGuard":null,"tryCatchPattern":"// Replace IIFE .catch with a top-level try/catch\ntry {\n  await init();\n} catch (err) {\n  console.error('boot failed', err);\n  process.exitCode = 1;\n}","preventionTips":["Treat `(async () => {...})()` at module scope as a migration artifact in ESM projects.","Preserve name isolation with a plain block `{ ... }` if that was the IIFE's purpose.","Keep error handling explicit — an un-caught rejected top-level await fails the module load."],"tags":["oxlint","unicorn","async","iife","top-level-await"],"backgroundTag":"top-level-await-migration","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}