SyntaxError: Cannot Use Import Statement Outside a Module — How to Fix It
SyntaxError: Cannot use import statement outside a module
What causes this
You’re using ES module syntax (import/export) in a file that Node.js treats as CommonJS. By default, Node.js treats .js files as CommonJS (which uses require()), not ES modules (which use import).
This also happens in:
- Jest tests that import ES module code
- TypeScript projects with wrong
modulesettings - Older Node.js versions that don’t fully support ES modules
Fix 1: Add “type”: “module” to package.json
Tell Node.js to treat all .js files as ES modules:
{
"name": "my-project",
"type": "module"
}
After this, import works in all .js files. If you have files that need CommonJS, rename them to .cjs.
Fix 2: Use the .mjs extension
If you don’t want to change the whole project, rename just the file using import:
mv app.js app.mjs
node app.mjs
.mjs files are always treated as ES modules regardless of package.json.
Fix 3: Use require() instead
If you want to stay in CommonJS:
// ❌ ES module syntax in CommonJS
import express from 'express';
// ✅ CommonJS syntax
const express = require('express');
For named exports:
// ❌ ES module
import { readFile } from 'fs/promises';
// ✅ CommonJS
const { readFile } = require('fs/promises');
Fix 4: Fix TypeScript configuration
If you’re using TypeScript, check your tsconfig.json:
{
"compilerOptions": {
"module": "commonjs",
"esModuleInterop": true,
"moduleResolution": "node"
}
}
With "module": "commonjs", TypeScript compiles import statements to require() calls. If you want actual ES modules:
{
"compilerOptions": {
"module": "ESNext",
"moduleResolution": "bundler"
}
}
And add "type": "module" to package.json.
Fix 5: Fix Jest configuration
Jest runs in CommonJS by default. If your source code uses ES modules:
// package.json
{
"jest": {
"transform": {
"^.+\\.(ts|tsx|js|jsx)$": "babel-jest"
}
}
}
Or use the experimental ESM support:
node --experimental-vm-modules node_modules/.bin/jest
A simpler alternative: switch to Vitest, which supports ES modules natively.
Fix 6: Dynamic import as a workaround
If you need to import an ES module from CommonJS code:
// CommonJS file that needs an ES module
async function main() {
const { default: chalk } = await import('chalk');
console.log(chalk.green('Hello'));
}
main();
How to prevent it
- Decide early: is your project CommonJS or ES modules? Set
"type": "module"(or don’t) inpackage.jsonfrom the start - For new projects, prefer ES modules — it’s the standard going forward
- If using TypeScript, make sure
moduleintsconfig.jsonmatches yourpackage.jsontype - When mixing module systems is unavoidable, use
.mjsfor ES modules and.cjsfor CommonJS