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
| Code | TS1378 |
|---|---|
| Message | 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's category | error |
| Listed under | Modules 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
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.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"types": []
},
"include": ["*.js"]
} What causes it
moduleis not set, or is set tocommonjs,es2015ores2020.targetis belowes2017, or not set (the 5.9 default ises5).
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".
const response = await fetch("/config.json");
export const config = await response.json();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
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-levelawaitis 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>withouttype="module"cannot use top-levelawaitwhatever the config says.
Sources
- TSConfig Reference: module · TypeScript
- TypeScript 3.8 release notes (top-level await) · TypeScript
- diagnosticMessages.json (TypeScript 5.9.3) · TypeScript on GitHub
Last reviewed 20 October 2026.