Javascript

ESLint - Error Must use import to load ES Module

27 September 2026 · 10 min read

ESLint - Error Must use import to load ES Module

Navigating the complexities of modern JavaScript development often involves meticulous code linting to ensure quality and consistency. However, developers frequently encounter the frustrating message: ESLint - Error: Must use import to load ES Module. This particular error indicates a fundamental mismatch in how your JavaScript modules are being interpreted—specifically, an attempt to use CommonJS require() syntax to import a file that is being treated as an ES Module, or vice-versa. Understanding the underlying differences between ES Modules (ESM) and CommonJS is paramount to resolving this issue, which is becoming increasingly common as Node.js and browser environments fully embrace the standardized module system. This guide will meticulously break down the causes of this error and provide actionable, expert-backed solutions to get your project running smoothly.

Understanding the Root Cause: ES Modules vs. CommonJS

The core of the “Must use import to load ES Module” error lies in the evolution of JavaScript’s module systems. Historically, Node.js introduced CommonJS (CJS) as its primary module system, utilizing require() and module.exports for importing and exporting code. This system was vital for server-side JavaScript development before a native standard existed.

However, with the advent of ECMAScript 2015 (ES6), the JavaScript language itself gained a standardized module system: ES Modules (ESM), characterized by import and export statements. ESM offers static analysis benefits, better tree-shaking for bundlers, and is the native module system for modern web browsers. The challenge arises when Node.js projects, traditionally CommonJS-based, begin to adopt ESM, leading to conflicts if not configured correctly. ESLint, as a static analysis tool, flags these mismatches to prevent runtime errors.

Node.js versions 13 and above introduced robust support for ES Modules, but the dual-module nature means explicit configuration is often required. Without clear directives, Node.js defaults to CommonJS for .js files, while .mjs files are treated as ESM and .cjs files as CJS. This distinction is critical because you cannot directly require() an ES Module, nor can you use import to load a CommonJS module without specific loaders or configurations. According to the official Node.js documentation, “Files ending in .mjs are always parsed as ES modules. Files ending in .cjs are always parsed as CommonJS. Files ending in .js are parsed as ES modules if the nearest parent package.json contains a top-level "type": "module" field.” This flexibility, while powerful, is also the source of many module resolution errors, including the ESLint warning we’re addressing.

Our experts have observed that many developers encounter this error when migrating older projects or integrating new, ESM-first libraries into existing CommonJS codebases. The linting error serves as a crucial early warning, preventing runtime crashes that might otherwise be harder to debug. Proper understanding of module resolution rules is the first step towards a stable project.

Common Scenarios Leading to the ESLint Error

The ESLint error “Must use import to load ES Module” typically manifests in a few recurring scenarios, all stemming from the fundamental clash between CommonJS and ES Module syntax within an environment that expects ESM or is attempting to reconcile both. Identifying your specific scenario is key to applying the correct fix.

  • Mixed Module Usage in Node.js: One of the most common causes is attempting to use require() in a file that Node.js or your build system (like Webpack or Rollup) has determined should be an ES Module. This often happens when you’ve set "type": "module" in your package.json, making all .js files in that package default to ESM, but you still have legacy require() calls.
  • Incorrect File Extensions: Using .js for an ES Module without the "type": "module" declaration, or conversely, using .mjs (which explicitly denotes an ES Module) but then trying to require() something within it. The file extension dictates how Node.js interprets the file.
  • Transpilation Issues with Babel/TypeScript: If you’re using a transpiler like Babel or TypeScript, they might be configured to output CommonJS modules (e.g., targeting an older Node.js environment) even if your source code uses import/export syntax. ESLint might then correctly identify that the source file is written as an ES Module, but the transpilation target creates a conflict.

Consider a situation where you’re building a new feature with modern JavaScript, using import statements, but your project’s main entry point is a legacy CommonJS file. If ESLint is configured to apply rules broadly, it might flag the require() within an import-centric file, or vice-versa. Another example is when a third-party library is published as an ES Module, and your CommonJS application tries to require() it directly. This will fail, as ESM files cannot be directly consumed by CommonJS require() without specific bridge configurations or dynamic imports. For more in-depth information on Node.js module resolution, the official Node.js documentation on Packages and Module Resolution is an invaluable resource.

Understanding these scenarios helps in diagnosing whether the problem lies with your code’s syntax, your project’s configuration, or your build process. It’s not just about fixing the ESLint error, but about ensuring your application functions correctly in its intended environment.

Practical Solutions to Resolve the "Must use import..." Error -------------------------------------------------------------

Resolving the ESLint - Error: Must use import to load ES Module typically involves aligning your module syntax with your project’s configuration or target environment. Here are the most effective strategies:

1. Standardizing with "type": "module" in package.json

For Node.js projects, the simplest and most recommended approach for new projects or those looking to fully embrace ESM is to declare your project as an ES Module package. This makes all .js files within your package default to ESM.

  1. Edit your package.json: Open your project’s package.json file and add the following top-level property: ``` { “name”: “my-project”, “version”: “1.0.0”, “type”: “module”, “main”: “index.js”, “scripts”: { “start”: “node index.js” } }
  2. Update your code: Ensure all your JavaScript files now use import and export statements. If you have any remaining require() calls for your own modules, convert them to import. For built-in Node.js modules (like fs, path), you can still use import: import fs from 'fs';.
  3. Handle external CommonJS dependencies: If you need to import a CommonJS module into an ES Module file, you can use dynamic import: const myModule = await import('commonjs-module'); or use a default import if the module exports a default: import commonjsModule from 'commonjs-module';.

This approach establishes a clear, consistent module system for your entire project, which ESLint will then correctly interpret. It’s a forward-thinking solution aligned with modern JavaScript development practices.

2. Using Appropriate File Extensions

If you cannot or do not wish to set "type": "module" for your entire project (e.g., in a dual-package scenario or legacy codebase), file extensions provide granular control:

  • For ES Modules: Rename files that use import/export syntax from .js to .mjs. Node.js will automatically treat these as ES Modules, regardless of the package.json "type" field.
  • For CommonJS Modules: Ensure files that use require()/module.exports are named .cjs if they need to coexist with .mjs files in an ESM-default project.

This method offers file-level control and Question & Answer :

I am currently setting up a boilerplate with React, TypeScript, styled components, Webpack, etc., and I am getting an error when trying to run ESLint:

Error: Must use import to load ES Module

Here is a more verbose version of the error:

/Users/ben/Desktop/development projects/react-boilerplate-styled-context/src/api/api.ts 0:0 error Parsing error: Must use import to load ES Module: /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/lib/definition.js require() of ES modules is not supported. require() of /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/lib/definition.js from /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/babel-eslint/lib/require-from-eslint.js is an ES module file as it is a .js file whose nearest parent package.json contains "type": "module" which defines all .js files in that package scope as ES modules. Instead rename definition.js to end in .cjs, change the requiring code to use import(), or remove "type": "module" from /Users/ben/Desktop/development projects/react-boilerplate-styled-context/node_modules/eslint/node_modules/eslint-scope/package.json 

The error occurs in every single one of my .js and .ts/ .tsx files where I only use import or the file doesn’t even have an import at all. I understand what the error is saying, but I don’t have any idea why it is being thrown when in fact I only use imports or even no imports at all in some files.

Here is my package.json file where I trigger the linter from using npm run lint:eslint:quiet:

{ "name": "my-react-boilerplate", "version": "1.0.0", "description": "", "main": "index.tsx", "directories": { "test": "test" }, "engines": { "node": ">=14.0.0" }, "type": "module", "scripts": { "build": "webpack --config webpack.prod.js", "dev": "webpack serve --config webpack.dev.js", "lint": "npm run typecheck && npm run lint:css && npm run lint:eslint:quiet", "lint:css": "stylelint './src/**/*.{js,ts,tsx}'", "lint:eslint:quiet": "eslint --ext .ts,.tsx,.js,.jsx ./src --no-error-on-unmatched-pattern --quiet", "lint:eslint": "eslint --ext .ts,.tsx,.js,.jsx ./src --no-error-on-unmatched-pattern", "lint:eslint:fix": "eslint --ext .ts,.tsx,.js,.jsx ./src --no-error-on-unmatched-pattern --quiet --fix", "test": "cross-env NODE_ENV=test jest --coverage", "test:watch": "cross-env NODE_ENV=test jest --watchAll", "typecheck": "tsc --noEmit", "precommit": "npm run lint" }, "lint-staged": { "*.{ts,tsx,js,jsx}": [ "npm run lint:eslint:fix", "git add --force" ], "*.{md,json}": [ "prettier --write", "git add --force" ] }, "husky": { "hooks": { "pre-commit": "npx lint-staged && npm run typecheck" } }, "resolutions": { "styled-components": "^5" }, "author": "", "license": "ISC", "devDependencies": { "@babel/core": "^7.5.4", "@babel/plugin-proposal-class-properties": "^7.5.0", "@babel/preset-env": "^7.5.4", "@babel/preset-react": "^7.0.0", "@types/history": "^4.7.6", "@types/react": "^17.0.29", "@types/react-dom": "^17.0.9", "@types/react-router": "^5.1.17", "@types/react-router-dom": "^5.1.5", "@types/styled-components": "^5.1.15", "@typescript-eslint/eslint-plugin": "^5.0.0", "babel-cli": "^6.26.0", "babel-eslint": "^10.0.2", "babel-loader": "^8.0.0-beta.6", "babel-polyfill": "^6.26.0", "babel-preset-env": "^1.7.0", "babel-preset-react": "^6.24.1", "babel-preset-stage-2": "^6.24.1", "clean-webpack-plugin": "^4.0.0", "dotenv-webpack": "^7.0.3", "error-overlay-webpack-plugin": "^1.0.0", "eslint": "^8.0.0", "eslint-config-airbnb": "^18.2.0", "eslint-config-prettier": "^8.3.0", "eslint-config-with-prettier": "^6.0.0", "eslint-plugin-compat": "^3.3.0", "eslint-plugin-import": "^2.25.2", "eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-prettier": "^4.0.0", "eslint-plugin-react": "^7.14.2", "eslint-plugin-react-hooks": "^4.2.0", "extract-text-webpack-plugin": "^3.0.2", "file-loader": "^6.2.0", "html-webpack-plugin": "^5.3.2", "husky": "^7.0.2", "prettier": "^2.4.1", "raw-loader": "^4.0.2", "style-loader": "^3.3.0", "stylelint": "^13.13.1", "stylelint-config-recommended": "^5.0.0", "stylelint-config-styled-components": "^0.1.1", "stylelint-processor-styled-components": "^1.10.0", "ts-loader": "^9.2.6", "tslint": "^6.1.3", "typescript": "^4.4.4", "url-loader": "^4.1.1", "webpack": "^5.58.2", "webpack-cli": "^4.2.0", "webpack-dev-server": "^4.3.1", "webpack-merge": "^5.3.0" }, "dependencies": { "history": "^4.10.0", "process": "^0.11.10", "react": "^17.0.1", "react-dom": "^17.0.1", "react-router-dom": "^5.2.0", "styled-components": "^5.2.1" } } 

Here is my .eslintrc file:

{ "extends": ["airbnb", "prettier"], "parser": "babel-eslint", "plugins": ["prettier", "@typescript-eslint"], "parserOptions": { "ecmaVersion": 8, "ecmaFeatures": { "experimentalObjectRestSpread": true, "impliedStrict": true, "classes": true } }, "env": { "browser": true, "node": true, "jest": true }, "rules": { "arrow-body-style": ["error", "as-needed"], "class-methods-use-this": 0, "react/jsx-filename-extension": 0, "global-require": 0, "react/destructuring-assignment": 0, "import/named": 2, "linebreak-style": 0, "import/no-dynamic-require": 0, "import/no-named-as-default": 0, "import/no-unresolved": 2, "import/prefer-default-export": 0, "semi": [2, "always"], "max-len": [ "error", { "code": 80, "ignoreUrls": true, "ignoreComments": true, "ignoreStrings": true, "ignoreTemplateLiterals": true } ], "new-cap": [ 2, { "capIsNew": false, "newIsCap": true } ], "no-param-reassign": 0, "no-shadow": 0, "no-tabs": 2, "no-underscore-dangle": 0, "react/forbid-prop-types": [ "error", { "forbid": ["any"] } ], "import/no-extraneous-dependencies": ["error", { "devDependencies": true }], "react/jsx-no-bind": [ "error", { "ignoreRefs": true, "allowArrowFunctions": true, "allowBind": false } ], "react/no-unknown-property": [ 2, { "ignore": ["itemscope", "itemtype", "itemprop"] } ] } } 

And I’m not sure if it is relevant, but here is also my tsconfig.eslint.json file:

{ "extends": "./tsconfig.json", "include": ["./src/**/*.ts", "./src/**/*.tsx", "./src/**/*.js"], "exclude": ["node_modules/**", "build/**", "coverage/**"] } 

How can I fix this?

Googling the error does not present any useful forums or raised bugs. Most of them just state not to use require in your files which I am not.

I think the problem is that you are trying to use the deprecated babel-eslint parser, last updated a year ago, which looks like it doesn’t support ES6 modules. Updating to the latest parser seems to work, at least for simple linting.

So, do this:

  • In package.json, update the line "babel-eslint": "^10.0.2", to "@babel/eslint-parser": "^7.5.4",. This works with the code above but it may be better to use the latest version, which at the time of writing is 7.19.1.
  • Run npm i from a terminal/command prompt in the folder
  • In .eslintrc, update the parser line "parser": "babel-eslint", to "parser": "@babel/eslint-parser",
  • In .eslintrc, add "requireConfigFile": false, to the parserOptions section (underneath "ecmaVersion": 8,) (I needed this or babel was looking for config files I don’t have)
  • Run the command to lint a file

Then, for me with just your two configuration files, the error goes away and I get appropriate linting errors.