# `deslop/lazy-import-at-top-level`

Flag a dynamic import() at module top level that is awaited or .then/.catch/.finally-ed during load (no laziness benefit); prefer a static import.

- **Category:** Correctness
- **Severity:** warn
- **Source:** deslop-js
- **Framework:** global
- **Enabled when:** react-doctor deadCode analysis enabled (default true); whole-project scan only — skipped in --diff/--staged modes
- **Documentation:** <https://github.com/millionco/deslop-js>

## Validation prompt

Use this to decide whether a fired diagnostic is real or a false positive.

Fires when deslop walks the top-level program body and finds a dynamic import settled during module evaluation: kind top-level-await-import (high confidence; a top-level `await import("x")` in a VariableDeclaration init or ExpressionStatement, reason 'top-level `await import("x")` runs synchronously before the module finishes loading anyway — there is no laziness benefit, prefer a static `import`') or kind top-level-then-import (medium confidence; a top-level `import("x").then/.catch/.finally(...)` statement — the detector matches the member property `then`, `catch`, or `finally` — reason 'top-level `import("x").then(...)` runs at module evaluation — prefer a static `import` and a regular function call unless the dynamic-import contract is intentional'). It never fires on import() inside a function, handler, lazy(), or route loader, because the detector only walks programNode.body. False positive to SUPPRESS: the top-level await is deliberate sequencing, not failed code-splitting — e.g. it conditionally selects an implementation at load (await import(isProd ? "./prod" : "./dev")), gates init on an env/feature check, or loads an optional/native peer dep inside try/catch so the module can be skipped on platforms where it is absent.

## Fix prompt

Use this once validation confirms the diagnostic is real.

When the import is unconditional, replace the top-level dynamic import with a static one: turn `const m = await import("./mod")` into `import * as m from "./mod"` (or the named/default form), and turn `import("./mod").then(fn)` into `import mod from "./mod"` plus a direct `fn(mod)` call — a top-level await/then already blocks module evaluation, so the static form has identical timing but is statically analyzable and tree-shakeable. Keep dynamic import() only when you actually want the chunk split off and loaded later, in which case move the import() inside the function, event handler, route loader, or React.lazy(() => import(...)) that should trigger it. See https://react.dev/reference/react/lazy
