0
0
Node.jsframework~15 mins

Installing packages (dependencies vs devDependencies) in Node.js - Mechanics & Internals

Choose your learning style9 modes available
Overview - Installing packages (dependencies vs devDependencies)
What is it?
In Node.js projects, packages are external code libraries that add features to your app. When you install these packages, you can save them as either dependencies or devDependencies. Dependencies are needed for your app to run, while devDependencies are only needed during development, like tools for testing or building. This distinction helps keep your app lightweight and organized.
Why it matters
Without separating dependencies from devDependencies, your app might include unnecessary code when running in production. This can make your app slower, larger, and less secure. Properly managing these packages ensures your app runs efficiently and only includes what it truly needs at runtime.
Where it fits
Before learning this, you should understand what Node.js and npm (Node Package Manager) are and how to create a basic project. After this, you can learn about package versioning, semantic versioning, and how to publish your own packages.
Mental Model
Core Idea
Dependencies are the packages your app needs to run, while devDependencies are only needed to build or test your app during development.
Think of it like...
Think of your app like a car: dependencies are the engine and wheels needed to drive, while devDependencies are the tools in the garage used to fix or improve the car but not needed while driving.
Project Folder
├── node_modules
│   ├── dependencies (runtime packages)
│   └── devDependencies (development tools)
├── package.json
│   ├── dependencies
│   └── devDependencies
└── app.js (your app code)
Build-Up - 7 Steps
1
FoundationWhat are Node.js packages
🤔
Concept: Understanding what packages are and why we use them in Node.js projects.
Packages are reusable pieces of code created by others or yourself that add features to your project. Instead of writing everything from scratch, you install these packages using npm, which manages them for you.
Result
You know that packages are external code libraries that help build your app faster and better.
Knowing what packages are is the first step to managing your project's code and dependencies effectively.
2
FoundationInstalling packages with npm
🤔
Concept: How to add packages to your project using npm commands.
You use commands like 'npm install package-name' to add a package. By default, this adds the package to your dependencies in package.json, meaning your app needs it to run.
Result
You can add packages to your project and see them listed under dependencies in package.json.
Understanding how to install packages is essential to using external code in your project.
3
IntermediateDifference between dependencies and devDependencies
🤔Before reading on: Do you think devDependencies are needed when your app runs in production? Commit to your answer.
Concept: Introducing the two types of package categories and their roles.
Dependencies are packages your app needs to work when running. DevDependencies are packages only needed during development, like testing tools or code formatters. You add devDependencies using 'npm install --save-dev package-name'.
Result
You can categorize packages correctly, keeping your production app lean and your development environment rich.
Knowing this separation helps you avoid bloating your app with unnecessary code in production.
4
IntermediateHow package.json tracks dependencies
🤔Before reading on: Do you think dependencies and devDependencies are stored in the same place inside package.json? Commit to your answer.
Concept: Understanding how npm records package types in package.json.
The package.json file has two separate sections: 'dependencies' and 'devDependencies'. When you install a package, npm adds it to the correct section based on your command. This file tells npm what to install when setting up your project.
Result
You can read and edit package.json to see which packages are for runtime and which are for development.
Understanding package.json structure helps you manage and troubleshoot your project's packages.
5
IntermediateInstalling packages for production vs development
🤔Before reading on: When you run 'npm install' on a production server, do devDependencies get installed by default? Commit to your answer.
Concept: How npm installs packages differently depending on environment and commands.
By default, 'npm install' installs both dependencies and devDependencies. But in production, you can run 'npm install --production' or set NODE_ENV=production to install only dependencies. This keeps production environments clean and efficient.
Result
You can control which packages get installed depending on where your app runs.
Knowing this prevents accidentally deploying unnecessary development tools to production.
6
AdvancedWhy separating dependencies improves app security and size
🤔Before reading on: Do you think including devDependencies in production can increase security risks? Commit to your answer.
Concept: Understanding the impact of package separation on app performance and security.
DevDependencies often include tools that are not hardened for production use and can increase your app's size and attack surface if deployed. Keeping them out of production reduces risk and speeds up deployment and startup times.
Result
Your production app is smaller, faster, and safer by excluding devDependencies.
Understanding this helps you build professional-grade apps that are optimized and secure.
7
ExpertHandling peerDependencies and optionalDependencies
🤔Before reading on: Are peerDependencies installed automatically like dependencies? Commit to your answer.
Concept: Exploring less common package types and their roles in complex projects.
peerDependencies are packages your package expects the host project to provide, not installed automatically. optionalDependencies are packages that can fail to install without breaking your app. Managing these correctly avoids conflicts and errors in large projects.
Result
You can handle complex dependency scenarios and avoid common pitfalls in package management.
Knowing these advanced package types prevents subtle bugs and version conflicts in professional projects.
Under the Hood
npm uses the package.json file to track which packages your project needs. When you run 'npm install', it reads dependencies and devDependencies separately and installs them into the node_modules folder. In production mode, npm skips devDependencies to keep the environment clean. This separation is enforced by npm's internal logic and environment variables like NODE_ENV.
Why designed this way?
This design evolved to solve the problem of bloated production environments and to improve security and performance. Early Node.js projects included all packages everywhere, causing slow startups and larger deployments. Separating devDependencies allows developers to keep development tools out of production, making apps leaner and safer.
package.json
├── dependencies
│   ├── express
│   └── lodash
├── devDependencies
│   ├── jest
│   └── eslint

npm install
├── installs dependencies + devDependencies (default)

npm install --production
├── installs dependencies only

node_modules
├── express
├── lodash
└── (jest and eslint only if devDependencies installed)
Myth Busters - 4 Common Misconceptions
Quick: Do you think devDependencies are installed automatically in production by default? Commit to yes or no.
Common Belief:DevDependencies are always installed wherever you run npm install.
Tap to reveal reality
Reality:By default, npm installs both dependencies and devDependencies, but in production mode (NODE_ENV=production or npm install --production), devDependencies are skipped.
Why it matters:Installing devDependencies in production can bloat your app and introduce unnecessary security risks.
Quick: Do you think dependencies and devDependencies can be used interchangeably without issues? Commit to yes or no.
Common Belief:It doesn't matter if a package is saved as a dependency or devDependency; the app will work the same.
Tap to reveal reality
Reality:Packages needed at runtime must be dependencies; devDependencies are not installed in production and will cause runtime errors if misclassified.
Why it matters:Misclassifying runtime packages as devDependencies can cause your app to crash in production.
Quick: Do you think peerDependencies are installed automatically like dependencies? Commit to yes or no.
Common Belief:peerDependencies are installed automatically when you install a package.
Tap to reveal reality
Reality:peerDependencies must be installed manually by the host project; npm does not install them automatically.
Why it matters:Ignoring peerDependencies can cause version conflicts and unexpected bugs in complex projects.
Quick: Do you think devDependencies increase your app's runtime size? Commit to yes or no.
Common Belief:DevDependencies add to the size of your app when it runs.
Tap to reveal reality
Reality:DevDependencies are not included in the production build or runtime if installed correctly, so they do not increase runtime size.
Why it matters:Understanding this helps optimize app size and performance by correctly managing packages.
Expert Zone
1
Some build tools may require devDependencies to be present even in production build steps, so environment setup matters.
2
Misusing devDependencies for runtime packages can cause subtle bugs that only appear after deployment.
3
PeerDependencies help avoid duplicate packages but require careful version management to prevent conflicts.
When NOT to use
If your project is a simple script or a one-off tool, strict separation may be unnecessary. Also, in monorepos or complex workspaces, alternative package managers like Yarn Workspaces or pnpm may handle dependencies differently.
Production Patterns
In production, teams often run 'npm ci --production' to install only dependencies exactly as locked in package-lock.json, ensuring consistent and minimal installs. CI/CD pipelines separate build and runtime environments to keep devDependencies out of production containers.
Connections
Software Packaging
Builds-on
Understanding dependencies in Node.js connects to the broader idea of software packaging, where managing external code is essential for any programming environment.
Supply Chain Management
Analogous pattern
Just like managing suppliers for raw materials (dependencies) versus tools used in the factory (devDependencies), software projects manage packages to optimize efficiency and cost.
Lean Manufacturing
Similar principle
Separating runtime and development packages is like removing waste in manufacturing, ensuring only necessary parts are in the final product to improve speed and quality.
Common Pitfalls
#1Installing a runtime package as a devDependency causes app crashes in production.
Wrong approach:npm install --save-dev express
Correct approach:npm install --save express
Root cause:Misunderstanding that devDependencies are not installed in production, so runtime packages must be saved as dependencies.
#2Running 'npm install' in production installs unnecessary devDependencies, bloating the app.
Wrong approach:npm install
Correct approach:npm install --production
Root cause:Not using production mode to skip devDependencies during production installs.
#3Ignoring peerDependencies leads to version conflicts and bugs.
Wrong approach:Installing a package without manually installing its peerDependencies.
Correct approach:Manually install peerDependencies as specified in package.json.
Root cause:Assuming npm installs peerDependencies automatically when it does not.
Key Takeaways
Dependencies are packages your app needs to run, while devDependencies are only needed during development.
Properly separating these keeps your production app smaller, faster, and more secure.
The package.json file tracks dependencies and devDependencies in separate sections to manage them effectively.
In production, use 'npm install --production' or set NODE_ENV=production to avoid installing devDependencies.
Advanced package types like peerDependencies require manual management to prevent conflicts.