'Cannot use import statement outside a module' — fix Node ESM
Quick answer: Cannot use import statement outside a module means Node loaded your file as CommonJS but it uses ESM import syntax. Pick one module system: set "type": "module" in package.json (or use a .mjs extension) to run it as ESM, or convert the imports to require for CommonJS. Don't mix the two in one file.
What the error looks like
Node throws a SyntaxError before your code even runs:
import express from 'express';
^^^^^^
SyntaxError: Cannot use import statement outside a module
# the inverse, requiring an ESM-only package from CJS:
Error [ERR_REQUIRE_ESM]: require() of ES Module not supported
Node decides a .js file is CommonJS unless told otherwise. ESM import in a CommonJS file is a syntax error; require() of an ESM-only package is the mirror-image failure.
Why it happens
No "type": "module"
A .js file defaults to CommonJS, so its import statements are invalid.
Mixing import and require
One file uses both syntaxes; Node can't be both module systems at once.
A dependency went ESM-only
A package you require() is now ESM-only and can't be loaded with require.
ts-node / Jest config
Tooling transpiles or resolves modules differently than your runtime expects.
Pick a lane in three steps
Decide: ESM or CommonJS
# Going ESM (modern): keep your 'import' syntax.
# Staying CommonJS: switch to require(). Don't half-and-half.Tell Node which one
// package.json for ESM
{ "type": "module" }
// or just name the file server.mjs
// for CommonJS, use: const express = require('express');Load ESM-only deps from CJS
// if you must stay CommonJS but a dep is ESM-only:
const mod = await import('that-esm-package'); // dynamic importCommit to one module system across the project
The lasting fix is consistency. Choose ESM (type: module + import everywhere) or CommonJS (require everywhere), align your TypeScript module/target and test runner to match, and use dynamic import() as the bridge when a single dependency forces the other system.
A broken start, caught before production
A module-system mismatch makes the app fail to start — which should never surprise you in production. Infraveil verifies a deploy before it runs on your own servers, so a process that won't boot is caught at the gate. Releases are approval-gated and recorded, with one-click rollback to the last version that started.
Frequently asked questions
What does 'Cannot use import statement outside a module' mean?
Node parsed your file as CommonJS, but it contains ESM import syntax, which is only valid in modules. You need to tell Node the file is a module, or use require instead.
How do I make Node treat my files as ES modules?
Add "type": "module" to package.json, or give the file an .mjs extension. Then import syntax is valid.
What is ERR_REQUIRE_ESM?
The opposite problem: you used require() on a package that is ESM-only. Either switch your project to ESM, or load it with a dynamic import().
Can I mix import and require?
Not in the same file. Pick one module system per project; use dynamic import() from CommonJS only as a bridge to an ESM-only dependency.