Skip to content

JavaScript and Node.js errorReferenceError: “require is not defined”

Code stops with ReferenceError: require is not defined, often with “in ES module scope”, or the same for __dirname or module. require() only exists in Node.js CommonJS files. Browsers never had it, and Node.js ES modules (a .mjs file, or a .js file with "type": "module" in package.json) do not define it either.

Short answer

In a Node.js ES module, replace require() with import, and __dirname with import.meta.dirname (Node.js 20.11 and later). If one package really needs require, create it with createRequire(import.meta.url). In the browser, use import and a bundler such as Vite, or a script tag, because the browser has no require. If the whole project should be CommonJS, remove "type": "module" from package.json or rename the file to .cjs.

Why require is missing, and the fix

  1. 01

    The file is an ES module

    “In most cases, the ES module import can be used to load CommonJS modules. If needed, a require function can be constructed within an ES module using module.createRequire().” Node.js, Modules: ECMAScript modules

    "type": "module" in package.json, or a .mjs extension, makes Node.js load the file as an ES module, where require, module.exports and __dirname do not exist. Switch to import and export, which can also load most CommonJS packages.

    // before
    const express = require('express');
    
    // after
    import express from 'express';
  2. 02

    You need require for one thing

    Some packages, JSON files or native addons are easier to load with require. Create a require function inside the ES module instead of converting the whole project.

    import { createRequire } from 'node:module';
    const require = createRequire(import.meta.url);
    const config = require('./config.json');
  3. 03

    __dirname or __filename is missing too

    “These CommonJS variables are not available in ES modules.” Node.js, Modules: ECMAScript modules

    Node.js does not define them in ES modules. Use import.meta.dirname and import.meta.filename on Node.js 20.11 and later, or build them from import.meta.url on older versions.

    const dir = import.meta.dirname;
    
    // older Node.js
    import { fileURLToPath } from 'node:url';
    import path from 'node:path';
    const dir2 = path.dirname(fileURLToPath(import.meta.url));
  4. 04

    The code runs in the browser

    Code copied from a Node.js example and loaded with a script tag, or a package meant for Node.js imported into front-end code, fails because browsers have no require. Use import with a bundler (Vite, webpack, Next.js), and pick packages that support the browser.

    <script type="module">
      import { format } from 'https://cdn.jsdelivr.net/npm/date-fns@3.6.0/+esm';
    </script>

Checked against the vendor’s docs on : Node.js: Modules: ECMAScript modules (differences from CommonJS); Node.js: Modules: Packages ("type" field).

Rather hand it over?

Fixed scope, fixed price, paid upfront. The work happens in writing; no call needed.

Related: “Cannot use import statement outside a module” · Node.js ERR_REQUIRE_ESM · Next.js “window is not defined”

Questions

More on this error

What is the difference from “Cannot use import statement outside a module”?

They are opposites. require is not defined means the file is an ES module and uses CommonJS syntax; Cannot use import statement means the file is CommonJS and uses ES module syntax. Make the syntax match how the file is loaded.

Should I add "type": "module" or remove it?

For new code, ES modules are the standard and work in Node.js and browsers. For an older project full of require(), removing "type": "module" (or renaming files to .cjs) is the smaller change.

Can you fix it for me?

If one bug is the whole problem, the App Fix Ticket covers it: a written diagnosis first, then the fix. If the app has more going on, the Launch Check is a written check of the whole app. Each issue found is rated critical, high, medium or low, with where it is and how it was confirmed. No issues worth fixing, no charge. If the Launch Check finds nothing rated medium or higher, Simon refunds the full $450. You keep the report either way. This applies to the first 10 Launch Checks bought after October 30, 2026.

A different error?

Describe it and get a written quote

Send the error and what you were doing. You get a written scope, a fixed price and a timeline; Simon replies by email, usually within one business day.