Fix 'cannot use import statement outside a module'

By

Learn how to fix the cannot use import statement outside a module error by adding type module to package.json in Node.js, or to your script tag in browsers.

~~~

The error Uncaught SyntaxError: cannot use import statement outside a module means you’re using the import keyword in a file that’s not treated as an ES module. In Node.js you fix it by adding "type": "module" to package.json. In the browser you fix it by adding type="module" to the script tag.

I stumbled on this error while importing a function from a JavaScript file.

This error occurs for one reason: you’re trying to use import and you’re not inside an ES module.

It can happen in a Node.js environment, or in the browser.

Why does this happen?

JavaScript has two module systems. Node.js started with CommonJS, where you load code with require(). ES modules, with import and export, arrived later as the standard.

The browser treats a plain <script> as a classic script, so import is not valid there. In Node.js the picture changed. On Node 24, syntax detection is on by default (it landed in Node 22.7 and Node 20.19). A .js file that starts with import or export runs as an ES module, so node file.js often just works.

The error still shows up when you set "type": "commonjs", when the file is .cjs, when a runner or a transpiler wraps the file as CommonJS, or on an older Node that has no detection. You have to tell that environment: this file is an ES module.

The fix in Node.js

I had to add a package.json file in the folder of the project and add:

{
  "type": "module"
}

With that field, Node.js treats every .js file in the project as an ES module, and import works. It also stops the MODULE_TYPELESS_PACKAGE_JSON warning Node prints when package.json has no type and detection has to re-parse the file.

Alternatively, you can rename the file from .js to .mjs. Node.js always treats .mjs files as ES modules, no package.json change needed. This is handy for a single standalone script.

The fix in the browser

In the browser, you have to add the type attribute with the value module when you load the script, like this:

<script type="module" src="./file.js"></script>

instead of

<script src="./file.js"></script>

A pitfall after the fix

Adding "type": "module" switches the whole project to ES modules. If some file in it still uses CommonJS, you’ll trade this error for a new one:

ReferenceError: require is not defined in ES module scope

Same story with __dirname and __filename, which don’t exist in ES modules. On Node 24 you can use import.meta.dirname and import.meta.filename instead.

The fix is to convert those files too: replace each require() with an import, and each module.exports with export. So before flipping the switch on a large existing project, check how much code still relies on require(). For a new project, set "type": "module" from day one and you’ll never see this error.

Tagged: Node.js · All topics

Want me to talk about your product? You can sponsor this site.

~~~

Related posts about node: