Ffile2fix
Sign in Get started

Fix SyntaxError: Cannot use import statement outside a module

SyntaxError: Cannot use import statement outside a module

The file uses ES module syntax (import ... from), but the environment is loading it as a classic script or CommonJS file, where import is not allowed. You need to either mark the file as an ES module or convert it to require()/a bundled script.

Also appears as: Uncaught SyntaxError: Cannot use import statement outside a module (browser console) · Warning: To load an ES module, set "type": "module" in the package.json or use the .mjs extension. · ReferenceError: require is not defined in ES module scope, you can use import instead · Jest encountered an unexpected token ... SyntaxError: Cannot use import statement outside a module

Common causes

  • Node project without "type": "module" in package.json, running a .js file that uses import
  • In the browser, a <script src="app.js"> tag missing type="module"
  • Jest running untransformed ESM code, or a dependency in node_modules that ships only ESM
  • A TypeScript build outputs ES modules (module: ESNext) but the result is run as CommonJS, or vice versa
  • Running a TypeScript file directly with node or an old ts-node setup
  • A WordPress theme or plugin enqueueing a file that uses import as a normal script

How to fix it

  1. Decide which module system you want. New Node 18+ projects can use ES modules throughout. Older projects and many tools still expect CommonJS; mixing both in one file is what triggers this error.
  2. Node: mark the package as ESM. Add "type": "module" to package.json, or rename the file to .mjs. Then use import everywhere in it and include file extensions in relative imports.
  3. Or switch the file to CommonJS. If the rest of the project uses require(), change import x from 'x' to const x = require('x'), or rename ESM files to .mjs and keep the others .cjs.
  4. Browser: use type="module". Load the script with <script type="module" src="/js/app.js"></script>. Module scripts are deferred automatically and must be served over HTTP(S), not opened via file://.
  5. Jest: transform or use native ESM. Use babel-jest or ts-jest so test files are transformed, add ESM-only packages to transformIgnorePatterns exceptions, or run Jest with node --experimental-vm-modules.
  6. WordPress: add the module attribute. On WordPress 6.5+ use wp_enqueue_script_module(); on older versions add type="module" via the script_loader_tag filter, or bundle the code into a classic script.

package.json + index.js (Node 18+)

// package.json
{
  "name": "my-app",
  "type": "module"
}

// index.js
import express from 'express';
import { routes } from './routes.js'; // extension required

How to stop it happening again

  • Choose ESM or CommonJS for the whole project and set "type" in package.json explicitly
  • Use .mjs/.cjs extensions for the exceptions
  • Keep TypeScript's module and moduleResolution settings (e.g. NodeNext) aligned with how the output runs

Frequently asked questions

What is the difference between ESM and CommonJS?

CommonJS uses require() and module.exports and was Node's original system. ES modules use import/export, the standard used by browsers; Node supports both but decides per file based on extension and the package.json "type" field.

After adding type module I get 'require is not defined'. Why?

Now every .js file is an ES module, so require() is unavailable. Convert those files to import, rename them to .cjs, or use createRequire from 'node:module' for a few cases.

Can I import an ESM-only package from CommonJS?

Use dynamic import() inside an async function. Recent Node versions (22.12+ and 20.19+) also allow require() of synchronous ES modules.