TypeScript error

TS1378: Top-level await with an older module setting

  • Error TS1378
  • Tested with TypeScript 5.9

error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', ... is reported for an await outside any function when the config's module or target does not allow it. The runtime may support top-level await perfectly well; the checker goes by the config.

The common trap is a jsconfig.json that sets target but not module. TypeScript 5.9 then picks an older module format (es2015 for a recent target, commonjs with no target at all), and both are outside the list in the message, even in a package with "type": "module".

At a glance

CodeTS1378
MessageTop-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
TypeScript's categoryerror
Listed underModules and imports
Depends on module, target
In .js files Reported when the file is checked: checkJs in jsconfig.json, or // @ts-check at the top of the file

The message is TypeScript's own text from its diagnostic messages file (Apache-2.0).

What it looks like

config.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: config.js(2,18): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. config.js(5,23): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher. 6.0.3 : differs, see why TypeScript 6.0.3, run 21 October 2026: differs from 5.9.3. No errors. 7.0.2 : differs, see why TypeScript 7.0.2, run 21 October 2026: differs from 5.9.3. No errors. checked 21 October 2026
const response = await fetch("/config.json");error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.

export const config = await response.json();error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
target set, module left out: the checker assumes an older module format.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "types": []
  },
  "include": ["*.js"]
}

What causes it

  • module is not set, or is set to commonjs, es2015 or es2020.
  • target is below es2017, or not set (the 5.9 default is es5).

How to fix it

Set module to nodenext (or es2022)

For Node.js, "module": "nodenext" with "type": "module" in package.json allows top-level await and implies a recent target. For a bundler, "module": "preserve" or "es2022" with "moduleResolution": "bundler".

config.js TypeScript 5.9.3 TypeScript 5.9.3, run 21 October 2026: No errors. 6.0.3 TypeScript 6.0.3, run 21 October 2026: the same as 5.9.3. No errors. 7.0.2 TypeScript 7.0.2, run 21 October 2026: the same as 5.9.3. No errors. checked 21 October 2026
const response = await fetch("/config.json");

export const config = await response.json();
module nodenext allows top-level await in an ES module.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "nodenext",
    "types": []
  },
  "include": ["*.js"]
}

Under TypeScript 6.0 and 7.0

Every example on this page also runs under TypeScript 6.0.3 and 7.0.2 when this site is built. One of them reports something different from 5.9.3, the version the page describes; the ✗ on its badge links to its entry below.

module defaults to esnext

TypeScript 6.0 and 7.0 · defaults that changed in 6.0

The pattern: Top-level await in a project whose config does not set module.

Why: Only the 6.0 default causes this. Without module, 5.9 took es2015 from the es2022 target, and top-level await needs es2022 or later (TS1378); 6.0 and 7.0 assume esnext, where it is allowed. Source: TypeScript 6.0 release notes: Simple default changes.

target set, module left out: the checker assumes an older module format config.js

TypeScript 5.9.3
config.js(2,18): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
config.js(5,23): error TS1378: Top-level 'await' expressions are only allowed when the 'module' option is set to 'es2022', 'esnext', 'system', 'node16', 'node18', 'node20', 'nodenext', or 'preserve', and the 'target' option is set to 'es2017' or higher.
TypeScript 6.0.3differs from 5.9.3

No errors.

TypeScript 7.0.2differs from 5.9.3

No errors.

What works in every version: Set module explicitly (nodenext for code Node.js runs, esnext with moduleResolution: bundler for bundled code), so every version reads the file the same way.

The example module nodenext allows top-level await in an ES module on this page shows it, with the same result under every version.

Gotchas

  • In a CommonJS file under nodenext (a package without "type": "module"), top-level await is a different error, TS1309, because CommonJS cannot wait at the top level at all.
  • The runtime has to load the file as a module too: a browser <script> without type="module" cannot use top-level await whatever the config says.

Sources

Last reviewed 20 October 2026.