How to fix ReferenceError: require is not defined in Node.js
This error occurs when attempting to use CommonJS require() syntax in code being treated as an ES module. Node.js uses different module systems, and require() is not available in ES module scope.
Quick fix
Fixes ERR_REQUIRE_ESM
cat package.json | grep '"type"'- Check your package.json for ES module configuration
- Convert require() to import statements
- Use createRequire to enable require() in ES modules
- Remove "type": "module" from package.json
cat package.json | grep '"type"'ReferenceError: require is not defined
What this error means
This error indicates that your code is attempting to use the CommonJS `require()` function, but Node.js is treating your file as an ES module where `require()` is not defined. This typically happens when your package.json includes `"type": "module"`, your file has a `.mjs` extension, or you're using ES module syntax elsewhere in the project. ES modules (ESM) and CommonJS are two different module systems in Node.js. CommonJS uses `require()` and `module.exports`, while ES modules use `import` and `export` statements. When Node.js treats a file as an ES module, it doesn't provide the CommonJS globals like `require`, `__dirname`, or `__filename`. The error message often includes "you can use import instead" as a hint to migrate to ES module syntax. This is part of Node.js's gradual transition toward ES modules as the standard module system.
Typical symptoms
- Error message: "ReferenceError: require is not defined in ES module scope"
- Error occurs when running Node.js scripts with require() statements
- File has .mjs extension or package.json contains "type": "module"
- Code works in CommonJS but fails when migrated to ES modules
- Lambda functions or serverless deployments fail with require errors
- Build tools or bundlers show module resolution errors
Common causes
- package.json includes "type": "module" which treats all .js files as ES modules
- File has a .mjs extension which explicitly marks it as an ES module
- Project is using ES module syntax elsewhere but some files still use require()
- Third-party dependency or build tool enforces ES module mode
- Attempting to use CommonJS patterns in an ES module environment
- Importing a CommonJS module incorrectly in ES module context
How to fix "ReferenceError: require is not defined"
First, verify if your project is configured to use ES modules:
cat package.json | grep '"type"'If you see "type": "module", this means all .js files are treated as ES modules. You have two options: remove this setting to use CommonJS, or convert your code to use ES module syntax.
The most straightforward solution is to use ES module syntax. Replace require() calls with import statements:
Before (CommonJS):
const fs = require('fs');
const express = require('express');
const myModule = require('./myModule');After (ES Module):
import fs from 'fs';
import express from 'express';
import myModule from './myModule.js';Note: ES modules require file extensions in relative imports (./myModule.js not ./myModule).
If you need to use require() in an ES module (for example, to load JSON files or CommonJS-only packages), create a require function:
import { createRequire } from 'module';
const require = createRequire(import.meta.url);
// Now you can use require()
const data = require('./config.json');
const oldModule = require('legacy-commonjs-package');This approach allows you to maintain ES module syntax while still accessing CommonJS modules when needed.
If you prefer to use CommonJS throughout your project, remove the ES module configuration:
Edit package.json:
{
"name": "your-project",
"version": "1.0.0",
// Remove this line:
// "type": "module"
}After removing this, all .js files will be treated as CommonJS modules, and require() will work normally.
You can be explicit about which module system each file uses by renaming:
For CommonJS modules:
mv script.js script.cjsFor ES modules:
mv script.js script.mjsFiles with .cjs extensions are always treated as CommonJS (can use require()), and files with .mjs extensions are always treated as ES modules (must use import), regardless of package.json settings.
If you're using other CommonJS globals like __dirname or __filename, replace them with ES module equivalents:
Before (CommonJS):
const path = require('path');
const configPath = path.join(__dirname, 'config.json');After (ES Module):
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const configPath = join(__dirname, 'config.json');Or in Node.js 20.11.0+, use the new built-in properties:
import { join } from 'path';
const configPath = join(import.meta.dirname, 'config.json');Advanced notes
Module System Detection: Node.js determines whether a file is CommonJS or ES module based on: (1) file extension (.mjs = ESM, .cjs = CommonJS, .js = depends on package.json), (2) nearest package.json's "type" field ("module" = ESM, "commonjs" or absent = CommonJS), (3) --input-type flag for stdin input.
Mixed Module Systems: You can use both module systems in the same project by being explicit with file extensions. Use .cjs for CommonJS files and .mjs for ES module files. This overrides the package.json "type" setting for specific files.
JSON Imports in ES Modules: To import JSON files in ES modules, use import assertions (experimental in older Node versions, stable in Node.js 17.5+):
import data from './config.json' assert { type: 'json' };Or use createRequire() as shown in the steps above.
Dynamic Imports: ES modules support dynamic imports which return promises and work in both CommonJS and ES modules:
const module = await import('./myModule.js');Top-Level Await: ES modules support top-level await, allowing you to use await outside of async functions. This is not available in CommonJS.
Build Tool Considerations: If using bundlers like webpack, Rollup, or esbuild, they may have their own module resolution logic. Check your bundler configuration if this error appears during builds rather than runtime.
Serverless Environments: AWS Lambda and other serverless platforms support both module systems. If deploying Lambda functions with ES modules, ensure your package.json includes "type": "module" and use .mjs extensions or import syntax consistently.
TypeScript Projects: When using TypeScript, set "module": "ESNext" or "module": "ES2020" in tsconfig.json to generate ES module output. If targeting CommonJS, use "module": "CommonJS".
Performance: ES modules are parsed before execution, enabling better optimization and tree-shaking. CommonJS modules are executed during loading, which can impact startup time but allows for conditional requires.
Frequently asked questions
- What does "ERR_REQUIRE_ESM" mean?
- js is treating your file as an ES module where require() is not defined. mjs extension, or you're using ES module syntax elsewhere in the project. js.
- How do I fix "ERR_REQUIRE_ESM"?
- This error occurs when attempting to use CommonJS require() syntax in code being treated as an ES module. Node.js uses different module systems, and require() is not available in ES module scope.
- What causes "ERR_REQUIRE_ESM"?
- package.json includes "type": "module" which treats all .js files as ES modules File has a .mjs extension which explicitly marks it as an ES module Project is using ES module syntax elsewhere but some files still use require()
- Is the "ERR_REQUIRE_ESM" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐Node.js Official Documentation
- ๐Node.js ECMAScript Modules Documentation(Official Docs)
- ๐
- ๐
- ๐