Skip to Content
Fix "Cannot use import statement outside a module"
Intermediate
0 likes
Tutorials

Fix "Cannot use import statement outside a module"

The file was loaded as a classic script or CommonJS, where import isn't allowed. The fix in the browser is type="module". In Node it's "type": "module" or .mjs, and recent npm init writes "type": "commonjs" for you.

"SyntaxError: Cannot use import statement outside a module" means the file was loaded as an old-style script or CommonJS file, and import isn't allowed there. The fix is to tell the browser or Node that the file is a module. Which fix you need depends on where the code runs, so first find that out.

Skip ahead: In the browser? Skip to "Fix 1: the browser". In Node? Skip to "Fix 2: Node.js".

What you're looking at

JavaScript has two ways to share code between files:

  • ES modules (the standard): import and export.
  • CommonJS (Node's original system): require() and module.exports.

Classic browser scripts are neither. import only works in an ES module, and the browser and Node each need to be told when a file is one.

Fix 1: the browser

In Chrome's console the error reads Uncaught SyntaxError: Cannot use import statement outside a module, pointing at your script. The script tag is missing type="module":

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

Change it to:

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

Two things change with type="module", so check them after the fix:

  1. Module scripts are deferred: they run after the HTML is parsed, so you don't need to put them at the bottom of <body> anymore.
  2. Opening the page by double-clicking the HTML file (a file:// address) blocks the imports with a CORS error. Serve the folder instead, for example npx serve in that folder, or your editor's Live Server, and open the http://localhost address it gives you.

Also check the import paths. In the browser, import { total } from "./cart.js" needs the ./ and the .js. A bare name like "dayjs" only works if you use a bundler like Vite or an import map.

Fix 2: Node.js

Node 24 prints something like this:

(node:1447762) Warning: Failed to load the ES module: /tmp/e/a.js. Make sure to set "type": "module" in the nearest package.json file or use the .mjs extension.
(Use `node --trace-warnings ...` to show where the warning was created)
/tmp/e/a.js:1
import fs from "node:fs";
^^^^^^

SyntaxError: Cannot use import statement outside a module

The warning above the error tells you the fix. Node decides how to load a .js file from the nearest package.json. Open it and look for "type":

{
  "name": "order-report",
  "type": "commonjs"
}

That's the cause in most new projects: recent versions of npm init -y write "type": "commonjs" for you. Change it to:

{
  "name": "order-report",
  "type": "module"
}

Or, from the terminal, npm pkg set type=module. Run the file again.

If you can't change package.json (for example, the rest of the project is CommonJS and you don't want to break it), rename just this file from .js to .mjs. A .mjs file is always an ES module, whatever package.json says. The opposite also exists: .cjs is always CommonJS.

⚠ Warning: Changing "type" to "module" affects every .js file in that folder and below it. Any file that uses require() or module.exports will now fail with ReferenceError: require is not defined in ES module scope, you can use import instead. In an existing project, search for require( first. Either convert those files to import, or rename them to .cjs.

The other errors you might hit right after

Once the file loads as a module, you may meet these:

  • Error [ERR_MODULE_NOT_FOUND]: Cannot find module '.../cart' imported from .../main.js followed by Did you mean to import "./cart.js"?: Node needs the file extension in relative imports. Add .js.
  • ReferenceError: require is not defined in ES module scope: you mixed require into a module. Use import, or import { createRequire } from "node:module" if you really need require for one old package.
  • ReferenceError: __dirname is not defined in ES module scope: modules don't have __dirname. In Node 20.11 and later, use import.meta.dirname.

When there's no package.json at all

With no package.json anywhere above the file, Node 24 looks at the code itself: if it contains import or export, it runs it as a module. So a loose test file works, and the same code fails once it's inside a project with "type": "commonjs". That's why "it worked a minute ago" is common with this error. Nothing in the file changed. It moved into a different folder.

💡 Tip: Pick one module system per project and write it down. For new code, that's ES modules: "type": "module" in package.json, import/export everywhere, .cjs only for the odd config file a tool insists on.

Tools that run your code

Test runners and build tools sometimes load files their own way. Vitest and Vite understand import out of the box. Older Jest setups use CommonJS and need extra configuration for ES modules. If the error only happens in tests, the fix is in the test runner's config, not in your code.

Checklist

  1. Browser: <script type="module">, served over http://, not file://.
  2. Node: "type": "module" in the nearest package.json, or .mjs.
  3. Relative imports have ./ and .js.
  4. No require left in module files.
  5. Only in tests? Check the test runner config.

Which one was it for you, and did the fix break any require() somewhere else?

About

Find where the error comes from, then fix it in the browser with type="module" or in Node with package.json type or .mjs, and handle the errors that show up right after. After this, import works and nothing else broke.

Responsible
Jay P
Last Update
09/02/2026
Reading Time
5 min
Was this helpful?
​ 0 ​ 0

Comments (0)

Sign in to comment

No comments yet.