Skip to content

Fixing ERR_REQUIRE_ESM error when using node-fetch

Problem

You're building a Discord bot using Node.js and encounter the error:

[ERR_REQUIRE_ESM]: require() of ES Module not supported

This error occurs when using node-fetch version 3.0.0 or higher with CommonJS require() syntax. Starting from version 3.0.0, node-fetch became a pure ES Module package that no longer supports CommonJS require() imports.

The problematic code looks like this:

js
const fetch = require('node-fetch'); // This causes the error in v3+

Solutions

Here are several approaches to resolve this issue:

Convert your project to use ES Modules instead of CommonJS:

  1. Update your package.json to include the module type:
json
{
  "type": "module",
  // ... other properties
}
  1. Replace require() statements with import syntax:
js
import fetch from 'node-fetch';

module.exports = {
  name: 'username',
  description: "this is the username command",
  async execute(message, args) {
    // Your code using fetch
  }
}

WARNING

If you set "type": "module", all files in your project must use ES Module syntax (import/export) instead of CommonJS (require/module.exports).

Solution 2: Use dynamic import()

If you prefer to keep your project as CommonJS, use dynamic imports:

js
module.exports = {
  name: 'username',
  description: "this is the username command",
  async execute(message, args) {
    const { default: fetch } = await import('node-fetch');
    
    // Rest of your code using fetch
  }
}

Solution 3: Downgrade to node-fetch v2

If you want to keep using require() syntax without modifying your project structure:

bash
npm uninstall node-fetch
npm install node-fetch@2.6.6

Then continue using:

js
const fetch = require('node-fetch');

TIP

While downgrading works, it's generally better to use the latest version for security updates and new features.

Solution 4: Use an alternative HTTP client

Consider using other HTTP client libraries that support CommonJS:

Using axios:

bash
npm install axios
js
const axios = require('axios');

// Replace fetch calls with axios
const response = await axios.get(`https://api.mojang.com/users/profiles/minecraft/${ign}`);
const data = response.data;

Using got:

bash
npm install got
js
const got = require('got');

// Replace fetch calls with got
const response = await got(`https://api.mojang.com/users/profiles/minecraft/${ign}`).json();

Complete Fixed Code Example

Here's your Discord bot command updated with ES Module syntax:

js
import fetch from 'node-fetch';

export default {
  name: 'username',
  description: "this is the username command",
  async execute(message, args) {
    if (args.length !== 1) {
      return message.channel.send("Please provide a valid username");
    }

    const ign = args[0];

    if (ign.length > 16 || ign.length < 3) {
      return message.channel.send("Username must be between 3-16 characters");
    }

    try {
      const uuidResponse = await fetch(`https://api.mojang.com/users/profiles/minecraft/${ign}`);
      const uuidData = await uuidResponse.json();
      const uuid = uuidData.id;

      if (uuid.length !== 32) {
        return message.channel.send("Invalid username");
      }

      const onlineInfoResponse = await fetch(`https://api.hypixel.net/status?key=${process.env.HYPIXEL_KEY}&uuid=${uuid}`);
      const onlineInfo = await onlineInfoResponse.json();

      if (onlineInfo.success) {
        if (onlineInfo.session.online) {
          message.channel.send("They are online");
        } else {
          message.channel.send("They are offline");
        }
      } else {
        message.channel.send("Hypixel API error");
      }
    } catch (error) {
      console.error(error);
      message.channel.send("An error occurred");
    }
  }
}

Security Note

Avoid hardcoding API keys in your code. Use environment variables instead:

bash
# Create a .env file
HYPIXEL_KEY=your_api_key_here

And use it in your code:

js
const onlineInfoResponse = await fetch(`https://api.hypixel.net/status?key=${process.env.HYPIXEL_KEY}&uuid=${uuid}`);

Understanding the Issue

ES Modules (ESM) and CommonJS are two different module systems in Node.js:

  • CommonJS: Uses require() and module.exports (older standard)
  • ES Modules: Uses import and export (modern standard)

When node-fetch v3+ switched to being a pure ES Module package, it could no longer be imported using CommonJS require() syntax, causing the ERR_REQUIRE_ESM error.

Best Practices

  1. Use ES Modules for new projects as it's the modern standard
  2. Keep dependencies updated for security and performance
  3. Use environment variables for sensitive information like API keys
  4. Add proper error handling with try-catch blocks

By following these solutions, you can resolve the ERR_REQUIRE_ESM error and continue developing your Discord bot successfully.