In the Node.js ecosystem, the distinction between dependencies and devDependencies in your package.json is a critical architectural choice. But how exactly do they impact the final artifacts sent to production?
The Core Difference
When you run npm install, both types are downloaded. However, when deploying to a production environment using npm install --production, only the items listed in the dependencies object are installed.
The "Tree-Shaking" Reality: If you are using a modern bundler like Webpack or Vite, the bundler only includes code that is actually imported in your source files. If a devDependency is never imported, it will never reach the client’s browser.
Impact on Build Pipelines
While devDependencies might not bloat your final JS bundle, they do affect:
- CI/CD Speed: More devDependencies mean longer
npm installtimes during your build process. - Security: Every package added is a potential vulnerability point, regardless of which section it sits in.
- Server Disk Space: If you don't prune your node_modules, your server storage will be consumed by tools like Test Runners and Linters.
// Correct practice for package.json
{
"dependencies": {
"react": "^18.0.0",
"axios": "^1.0.0"
},
"devDependencies": {
"eslint": "^8.0.0",
"jest": "^29.0.0",
"typescript": "^5.0.0"
}
}