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):
importandexport. - CommonJS (Node's original system):
require()andmodule.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:
- 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. - Opening the page by double-clicking the HTML file (a
file://address) blocks the imports with a CORS error. Serve the folder instead, for examplenpx servein that folder, or your editor's Live Server, and open thehttp://localhostaddress 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.jsfollowed byDid 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 mixedrequireinto a module. Useimport, orimport { createRequire } from "node:module"if you really needrequirefor one old package.ReferenceError: __dirname is not defined in ES module scope: modules don't have__dirname. In Node 20.11 and later, useimport.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
- Browser:
<script type="module">, served overhttp://, notfile://. - Node:
"type": "module"in the nearestpackage.json, or.mjs. - Relative imports have
./and.js. - No
requireleft in module files. - 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
Reviews
Sign in to write a reviewComments (0)
Sign in to commentNo comments yet.