The ESLint error 'X' should be listed in the project's dependencies, not devDependencies (from the rule import/no-extraneous-dependencies) is a helpful guardrail that ensures your project's dependencies are correctly organized.
This error occurs for two main reasons:
- A package that is only needed for development (like a testing library) is being imported into your production source code.
- A package that is needed for production (like React or Axios) was accidentally installed as a
devDependency.
This guide will explain the difference between dependencies and devDependencies and show you how to solve this error correctly for both scenarios.
The Core Concept: dependencies vs. devDependencies
Your package.json file has two main sections for listing project dependencies:
dependencies: These are packages that your application needs to run in production. Examples includereact,axios,lodash, anddate-fns.devDependencies: These are packages that are only needed for development and testing. Examples includejest,eslint,prettier,@testing-library/react, andwebpack.
Scenario 1: Importing a devDependency into a Source File
This often happens in test files, Storybook files, or other development-specific files. The linter sees you importing a devDependency (like @testing-library/react) and, by default, flags it as an error because it doesn't know this file is only for development.
Example of problem:
// src/App.test.js
// ⛔️ ESLint Error: '@testing-library/react' should be listed in the
// project's dependencies, not devDependencies.
import { render } from '@testing-library/react';
import App from './App';
test('renders learn react link', () => {
render(<App />);
});Solution for Scenario 1: Configure ESLint for Test Files
The correct solution is to tell ESLint that it's okay to import devDependencies in your test and configuration files. You do this by updating the import/no-extraneous-dependencies rule in your .eslintrc.js (or .eslintrc.json) file.
Solution:
// .eslintrc.js
module.exports = {
// ... other config
rules: {
'import/no-extraneous-dependencies': [
'error',
{
'devDependencies': [
'**/*.test.js', // Match test files
'**/*.test.jsx',
'**/*.spec.js',
'**/*.spec.jsx',
'./storybook/**', // Match storybook config files
'**/*.stories.jsx'
]
}
]
},
};Scenario 2: A Production Package is in devDependencies
This happens when a package that is required for your application to run was installed incorrectly using npm install --save-dev or yarn add --dev.
Problem: your package.json looks like this:
{
"dependencies": {},
"devDependencies": {
"axios": "^1.0.0" // ⛔️ Incorrect: axios is needed in production.
}
}Solution for Scenario 2: Move the Package to dependencies
The solution is to move the package from devDependencies to dependencies.
Recommended Solution: The cleanest way to do this is to uninstall and reinstall the package correctly.
npm uninstall axios
npm install axiosThis will automatically update your package.json and package-lock.json files correctly.
Alternatively, you can manually edit your package.json file, moving the "axios": "..." line from the devDependencies object to the dependencies object, and then run npm install.
Conclusion
The import/no-extraneous-dependencies error is a valuable tool for maintaining a clean and correct package.json.
- If the error occurs in a test, story, or config file, the correct solution is to update your
.eslintrc.jsfile to allowdevDependenciesimports in those specific files. - If the error occurs in your application source code (e.g., a React component), the package is almost certainly in the wrong section. The correct solution is to move it from
devDependenciestodependenciesin yourpackage.json.