dependencies vs devDependencies
A package.json categorizes dependencies into four buckets. Understanding the exact difference between them is critical for bundle size optimization.
The Four Dependency Buckets
A package.json file categorizes dependencies into four distinct buckets. Understanding the exact difference between them is critical for bundle size optimization, CI/CD pipeline speed, and security.
**dependencies** are your core production requirements. If your app imports a library (like react or lodash) to run in production, it goes here. **devDependencies** are your local tooling requirements. Things like jest, eslint, and typescript are needed to build and test the app, but they do not belong on the final production server.
Strict Contracts and Optional Enhancements
**peerDependencies** act as a strict contract. They tell npm: 'My package needs the host application to install this specific dependency'. This prevents installing multiple conflicting copies of large libraries like React.
Finally, **optionalDependencies** are non-critical features (often OS specific native bindings); if they fail to compile, the install continues successfully anyway.
Production Installs and ERESOLVE
When deploying to production or building a Docker container, you should run npm install --production (or --omit=dev). This tells npm to skip downloading and extracting everything in devDependencies, significantly reducing build time and the final image size.
Since npm version 7, peerDependencies are installed automatically by default. However, if the host application has a conflicting version installed, npm will immediately halt the installation and throw an ERESOLVE error. You can override this strict behavior by passing the --legacy-peer-deps flag to force npm to ignore the conflict and install anyway.
Dependency Deployment Simulator
Toggle between development and production install modes. Observe which dependencies actually ship to the production server and how peer and optional dependencies behave.
ERESOLVE unable to resolve dependency tree
Conflicting peer dependency: react-dom@"^17.0.0" from the root project disagrees with "^18.2.0".
Remember this
dependenciesare shipped to production;devDependenciesare skipped during production installs.- Use
--omit=devor setNODE_ENV=productionto skip dev dependencies in CI/CD. - npm v7+ automatically installs
peerDependenciesand throwsERESOLVEerrors on version conflicts. - If an
optionalDependencyfails to install (e.g., native compilation error), npm ignores the failure and succeeds.
Done with this concept?
Mark it complete to track your progress. No login needed.