This error occurs when ts-node detects ES module syntax (import/export) in your TypeScript code but ESM support is not enabled. ts-node requires explicit ESM configuration to work with ES modules, which is common in modern TypeScript projects using module: "ESNext" or similar settings.
The error "Cannot use 'module' option with ts-node without 'esm'" happens when ts-node encounters ES module syntax (import/export statements) in your TypeScript code, but the runtime environment is not configured to support ES modules. ts-node needs to know whether to treat your code as CommonJS or ES modules. When your tsconfig.json specifies a module system like "ESNext", "ES2020", or "ES2015", but you're running ts-node without ESM flags, ts-node cannot properly execute the code. This is a configuration mismatch between your TypeScript compiler settings and your Node.js runtime configuration. TypeScript may be configured to output ES modules, but Node.js (and by extension ts-node) needs explicit instructions to load ES modules rather than the default CommonJS modules.
First, verify what module system your TypeScript is configured to use:
// tsconfig.json
{
"compilerOptions": {
"module": "ESNext", // or "ES2020", "ES2015"
// ... other options
}
}If your module is set to an ES module value (ESNext, ES2020, ES2015, etc.), you need ESM support.
When running ts-node with ES module configuration, add the --esm flag:
# For direct execution
npx ts-node --esm your-file.ts
# For ts-node/register
node --loader ts-node/esm --experimental-specifier-resolution=node your-file.tsThis tells ts-node to enable ES module support.
If your project uses ES modules, add this to your package.json:
{
"type": "module",
"scripts": {
"start": "ts-node --esm src/index.ts"
}
}This tells Node.js to treat .js files as ES modules by default.
You can configure ts-node to always use ESM by creating a tsconfig.json for ts-node:
// tsconfig.json
{
"ts-node": {
"esm": true,
"experimentalSpecifierResolution": "node"
},
"compilerOptions": {
"module": "ESNext"
}
}Or use a ts-node configuration file:
// .ts-noderc.json
{
"esm": true,
"experimentalSpecifierResolution": "node"
}If you continue to have issues, try alternative approaches:
1. Use tsx instead of ts-node:
npx tsx your-file.ts2. Compile first, then run:
npx tsc
node dist/index.js3. Use Node.js with ts-node/esm loader:
node --loader ts-node/esm --experimental-specifier-resolution=node your-file.tsEnsure your Node.js version supports ES modules:
- Node.js 12.17.0+ for experimental ES modules
- Node.js 14.13.0+ for stable ES module support
- Node.js 16.0.0+ for improved ES module features
Check your version:
node --versionUpdate if necessary:
# Using nvm
nvm install --lts
nvm use --ltsUnderstanding the module systems:
- CommonJS: Node.js's original module system using require() and module.exports
- ES Modules (ESM): JavaScript's standard module system using import and export
Why this happens: TypeScript can compile to either module system. When you set "module": "ESNext" in tsconfig.json, TypeScript outputs ES module syntax. However, Node.js defaults to CommonJS, so ts-node needs explicit configuration to handle ES modules.
Performance considerations: ESM loading can be slightly slower than CommonJS due to asynchronous nature. For development, the difference is negligible, but for production, consider pre-compilation.
Migration path: If migrating from CommonJS to ESM:
1. Update package.json with "type": "module"
2. Change file extensions from .js to .mjs or use package.json type
3. Update all import/export statements
4. Configure ts-node with --esm flag
Common pitfalls:
- Mixed module systems in the same project
- Third-party packages that don't support ESM
- Different behavior between development (ts-node) and production (compiled)
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript