Top-level await in TypeScript
The error "Top-level 'await' expressions are only allowed when the 'module' option is set to 'esnext' or 'system', and the 'target' option is set to 'es2017' or higher" occurs when trying to use await
outside of an async function in TypeScript without proper configuration.
Understanding the Problem
Top-level await allows you to use await
at the top level of a module without wrapping it in an async function. This feature requires specific TypeScript compiler settings:
module
must be set toesnext
orsystem
target
must bees2017
or higher
Solutions
Method 1: Configure tsconfig.json Properly
Update your tsconfig.json
with the correct settings:
{
"compilerOptions": {
"lib": ["es2020"],
"module": "es2022",
"moduleResolution": "node",
"target": "es2022",
"outDir": "dist"
}
}
WARNING
When compiling with tsc filename.ts
, TypeScript ignores tsconfig.json
. Always compile using tsc
without filename arguments to use your configuration.
Method 2: Use tsx for TypeScript Execution
tsx
is a modern tool that runs TypeScript files directly without complex setup:
- Ensure
"type": "module"
in yourpackage.json
- Install tsx:
npm install tsx
- Run your TypeScript file:
npx tsx file.ts
Method 3: Wrap in Async Function (Legacy Approach)
If you can't modify your TypeScript configuration, wrap your await calls:
const createAccount = async () => {
const account = await stripe.accounts.create({
type: 'express',
});
return account;
};
createAccount().then(account => {
// Handle the account object
});
Best Practices
- Modern Approach: Use
tsx
for development and propertsconfig.json
settings for production - File Extensions: Use
.mts
extension for ES modules with top-level await - Module Resolution: Set
"moduleResolution": "node"
for Node.js environments
TIP
Top-level await is natively supported in modern Node.js versions (v14.8+). Ensure you're using a recent Node.js version for best compatibility.
Common Pitfalls
- Compiling with
tsc filename.ts
instead of justtsc
- Missing
"type": "module"
inpackage.json
- Using outdated Node.js versions that don't support ES modules
By following these solutions, you can successfully use top-level await in your TypeScript projects with proper configuration and tooling.