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:
const fetch = require('node-fetch'); // This causes the error in v3+
Solutions
Here are several approaches to resolve this issue:
Solution 1: Use ES Modules syntax (Recommended)
Convert your project to use ES Modules instead of CommonJS:
- Update your
package.json
to include the module type:
{
"type": "module",
// ... other properties
}
- Replace
require()
statements withimport
syntax:
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:
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:
npm uninstall node-fetch
npm install node-fetch@2.6.6
Then continue using:
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:
npm install axios
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:
npm install got
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:
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:
# Create a .env file
HYPIXEL_KEY=your_api_key_here
And use it in your code:
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()
andmodule.exports
(older standard) - ES Modules: Uses
import
andexport
(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
- Use ES Modules for new projects as it's the modern standard
- Keep dependencies updated for security and performance
- Use environment variables for sensitive information like API keys
- 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.