Fixing 'SyntaxError: Cannot use import statement outside a module' in Node.js

beginner💚 Node.js2026-03-29| Node.js (v12.22.0, v14.17.0, and all modern versions), Windows, macOS, Linux

Error Message

SyntaxError: Cannot use import statement outside a module
#nodejs#javascript#backend#es-modules#syntax-error

Quick Solutions

If you need to fix this error immediately, use one of these two industry-standard methods:

  • The Project-Wide Fix: Open package.json and add "type": "module" to the root object.
  • The Single-File Fix: Change your file extension from .js to .mjs.
// your package.json should look like this:
{
  "name": "my-node-app",
  "version": "1.0.0",
  "type": "module",
  "dependencies": { ... }
}

The Root Cause

Node.js was built in 2009 using CommonJS, a module system that uses require(). Modern JavaScript now uses ECMAScript Modules (ESM), which relies on import and export. These two systems handle variables and loading differently.

By default, Node.js treats every .js file as a CommonJS module. When the engine encounters an import statement in a file it expects to be CommonJS, it stops execution and throws this error:

SyntaxError: Cannot use import statement outside a module

To use modern syntax, you must explicitly signal to Node.js that your environment supports ES Modules.

Method 1: The package.json Approach (Recommended)

This is the most efficient way to manage modern Node.js projects. Setting the type field ensures that every .js file in your directory—and all its subdirectories—is treated as an ES Module.

  • Find the package.json file in your project root.
  • Insert "type": "module" into the main configuration block.
  • Restart your application by running node app.js.

One important note: This change disables require(). If you try to use const fs = require('fs') in a module, Node will throw an error. You must convert those lines to import fs from 'fs' or rename specific legacy files to .cjs.

Method 2: Using the .mjs Extension

Sometimes you don't want to change the configuration for an entire project. In these cases, the .mjs extension is your best friend. Node.js always treats .mjs files as ES Modules, regardless of what your package.json says.

  • Rename server.js to server.mjs.
  • Execute the file using node server.mjs.

This approach works well for small scripts or when you are gradually migrating a large codebase to modern JavaScript.

Method 3: Transpiling with TypeScript

If you are using TypeScript, you might encounter this error if your configuration targets an older version of Node. Your tsconfig.json acts as a bridge, converting your import statements into require calls that older Node versions understand.

// tsconfig.json
{
  "compilerOptions": {
    "module": "CommonJS",
    "target": "ES2020",
    "esModuleInterop": true
  }
}

Using ts-node or tsx to run your files handles this conversion in memory, preventing the SyntaxError during development.

Testing the Fix

Verify your setup by creating a file named check-version.js with the following code:

// check-version.js
import { versions } from 'process';
console.log("Node.js Engine Version:", versions.node);

If you enabled "type": "module", run node check-version.js. If it logs your version (e.g., 20.10.0) without crashing, your environment is correctly configured.

Common Hurdles

  • Node.js Versioning: ESM became stable in Node.js v12.17.0. If you are stuck on an older version like v10, you must upgrade to use import without experimental flags.
  • Explicit Extensions: Unlike CommonJS, ESM requires full file extensions. You cannot write import { auth } from './auth'; you must write import { auth } from './auth.js'.
  • Directory Imports: Importing a folder to automatically load index.js no longer works in ESM. You must point directly to the file path.

Resources

Related Error Notes