jsconfig.json option

esModuleInterop and allowSyntheticDefaultImports

  • Default false
  • Since TypeScript 2.7

Many npm packages are CommonJS and declare their types with export =. Importing one as import express from "express" needs the checker to accept a default import that the package does not literally have. allowSyntheticDefaultImports allows that in the types; esModuleInterop also changes the JavaScript tsc writes, and turns on allowSyntheticDefaultImports.

In a .js project you rarely touch either: a file named jsconfig.json defaults allowSyntheticDefaultImports to true, module: "nodenext" and "preserve" imply both, and moduleResolution: "bundler" implies allowSyntheticDefaultImports. The failing example has to switch it off on purpose (TS1259).

At a glance

Write Nothing: a jsconfig.json turns on allowSyntheticDefaultImports, and nodenext and preserve imply both
On the command line --esModuleInterop
Type boolean
Default in TypeScript 5.9 false (on when module is node16 to nodenext, or preserve)
Default from TypeScript 6.0 true, and false can no longer be set (TypeScript 6.0)
TypeScript's description Emit additional JavaScript to ease support for importing CommonJS modules. This enables 'allowSyntheticDefaultImports' for type compatibility.

The description is quoted from TypeScript's own option list (Apache-2.0); see the notices.

Examples

main.js Error confirmed 5.9.3 TypeScript 5.9.3, run 21 October 2026: main.js(2,8): error TS1259: Module '"/project/node_modules/@types/express/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag 6.0.3 : differs, see why TypeScript 6.0.3, run 21 October 2026: differs from 5.9.3. error TS5107: Option 'allowSyntheticDefaultImports=false' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error. main.js(2,8): error TS1259: Module '"/project/node_modules/@types/express/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag 7.0.2 : differs, see why TypeScript 7.0.2, run 21 October 2026: differs from 5.9.3. jsconfig.json(10,37): error TS5108: Option 'allowSyntheticDefaultImports=false' has been removed. Please remove it from your configuration. checked 21 October 2026
import express from "express";error TS1259: Module '"/project/node_modules/@types/express/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag

export const app = express();
allowSyntheticDefaultImports off: a default import of a CommonJS package.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "esnext",
    "types": [],
    "moduleResolution": "bundler",
    "allowSyntheticDefaultImports": false
  },
  "include": [
    "*.js"
  ]
}
main.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
import express from "express";

export const app = express();
The jsconfig.json default: the same import passes.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "esnext",
    "types": [],
    "moduleResolution": "bundler"
  },
  "include": [
    "*.js"
  ]
}

Why esModuleInterop is mostly about output

The "additional JavaScript" in TypeScript's description is the helper code tsc adds when it writes CommonJS output. With noEmit there is no output, so for a checked JavaScript project only the type side matters, which is allowSyntheticDefaultImports.

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.

allowSyntheticDefaultImports: false is deprecated, then removed

TypeScript 6.0 and 7.0 · options 6.0 deprecates and 7.0 removes

The pattern: A config that sets allowSyntheticDefaultImports (or esModuleInterop) to false, and a default import of a CommonJS package such as Express.

Why: Per the 6.0 release notes these options can no longer be false: 6.0 reports the setting as deprecated (TS5107) and still applies it, so the default import keeps its TS1259; 7.0 reports it as removed (TS5108) and always uses the safer interop, so the default import works and TS1259 is gone. Source: TypeScript 6.0 release notes: Deprecated: --esModuleInterop false and --allowSyntheticDefaultImports false.

allowSyntheticDefaultImports off: a default import of a CommonJS package main.js

TypeScript 5.9.3
main.js(2,8): error TS1259: Module '"/project/node_modules/@types/express/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag
TypeScript 6.0.3differs from 5.9.3
error TS5107: Option 'allowSyntheticDefaultImports=false' is deprecated and will stop functioning in TypeScript 7.0. Specify compilerOption '"ignoreDeprecations": "6.0"' to silence this error.
main.js(2,8): error TS1259: Module '"/project/node_modules/@types/express/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flag
TypeScript 7.0.2differs from 5.9.3
jsconfig.json(10,37): error TS5108: Option 'allowSyntheticDefaultImports=false' has been removed. Please remove it from your configuration.

What works in every version: Remove the option (or set esModuleInterop: true) and keep the default import.

server.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
import express from "express";

export const app = express();
The same import with esModuleInterop on.
jsconfig.json for this example
{
  "compilerOptions": {
    "checkJs": true,
    "noEmit": true,
    "strict": true,
    "target": "es2022",
    "module": "esnext",
    "types": ["node"],
    "moduleResolution": "bundler",
    "esModuleInterop": true
  },
  "include": ["*.js"]
}

Gotchas

  • Under nodenext, what a default import of a CommonJS package gives you follows Node.js: the whole module.exports object. A package whose types were written for bundler interop can look different there; trust what Node.js does at run time.

Sources

Last reviewed 20 October 2026.