Last updated: Feb 28, 2024
Reading time·3 min
The error "Module can only be default-imported using esModuleInterop flag" occurs when we try to import a CommonJS module into an ES6 module.
To solve the error, set the esModuleInterop
option to true
in your
tsconfig.json
file.
Here is an example of how the error occurs.
// ⛔️ Error: Module '"path"' can only be // default-imported using the 'esModuleInterop' flag ts(1259) // This module is declared with using 'export =', and // can only be used with a default import when // using the 'esModuleInterop' flag. import path from 'path'; console.log(path.join(__dirname, './another-file.ts')); export const num = 42;
The issue is that path
is a CommonJS module that uses the exports
and
require
syntax and we are trying to import it into an
ES6 module
using a default import.
esModuleInterop
option to true
To solve the error, set the esModuleInterop
option to true
in your
tsconfig.json file.
{ "compilerOptions": { "esModuleInterop": true, "allowSyntheticDefaultImports": true, // ... rest } }
Now our import works as intended.
import path from 'path'; export const num = 42; // ✅ "/home/borislav/Desktop/typescript/src/another-file.ts" console.log(path.join(__dirname, './another-file.ts'));
The esModuleInterop
option is set to false
by default, which causes it to treat CommonJS modules
similar to ES6 modules.
This causes some issues and setting esModuleInterop
to true
fixes these
issues.
The esModuleInterop
setting changes the behavior of the compiler with two
helper functions that provide a shim to make the emitted JavaScript compatible.
When you set esModuleInterop
to true
, you are also enabling the
allowSyntheticDefaultImports
option.
When enabled, allowSyntheticDefaultImports
allows us to write our imports
without using an asterisk *
when the module doesn't explicitly specify a
default export.
import React from 'react'; import path from 'path'; import fs from 'fs';
Instead of:
import * as React from 'react'; import * as path from 'path'; import * as fs from 'fs';
For example, the path
module doesn't provide a default export, so if we try to
import it with allowSyntheticDefaultImports
set to false
, we would get the
error.
// ⛔️ Error: Module '"path"' can only be // default-imported using the 'esModuleInterop' flag ts(1259) import path from 'path';
The cause of the error is that there is no default
object that we can import
from the module.
import * as X
syntaxAn alternative approach is to use the import * as x
syntax.
import * as path from 'path'; export const num = 42; // ✅ "/home/borislav/Desktop/typescript/src/another-file.ts" console.log(path.join(__dirname, './another-file.ts'));
Note that imports such as import * as x
only account for properties that are
owned (not inherited via the prototype chain).
If importing a module that uses inherited properties, you have to use the
default import syntax - import path from 'path'
.
I've also written a detailed guide on how to import values from another file in TS.
You can learn more about the related topics by checking out the following tutorials: