Frontend
easy
junior
What are devDependencies, and how are they different from dependencies?
`dependencies` are needed at runtime; `devDependencies` are only needed for building, testing, or linting. Consumers of your package install dependencies but skip devDependencies.
4 min read·~6 min to think through
package.json splits packages into buckets that affect what gets installed where:
dependencies— needed when the code actually runs (React, lodash, your DB driver).devDependencies— only needed at dev time (TypeScript, ESLint, Jest, Vite).peerDependencies— packages the consumer must provide (e.g., a React component library declaresreactas a peer so it shares the host's React).optionalDependencies— installs are best-effort; failures don't break install.
Why the split matters:
- Library consumers. When your package is installed as a dependency by someone else, npm installs your
dependenciesbut not yourdevDependencies. Putting Jest independencieswould force every consumer to download Jest. - Production installs.
npm ci --omit=dev(orNODE_ENV=production npm installhistorically) skips dev deps, shrinking Docker images significantly. - Dependency hygiene. Treating dev tooling as separate makes audits easier — a CVE in your bundler doesn't ship to prod runtimes.
For an application (not a library), the split matters less for the consumer (there is none), but it still affects production install size and CI.
Code
Follow-up questions
- •Why are @types/* packages typically devDependencies?
- •What's a peerDependency, and how does it differ from devDependencies?
- •What does `npm install --save-dev X` do?
Common mistakes
- •Putting test tooling in `dependencies` and bloating consumers' installs.
- •Putting actual runtime libs in `devDependencies` and breaking production at startup.
- •Forgetting `peerDependencies` for a component library, leading to duplicate React copies.
Performance considerations
- •Production-only installs cut Docker layer size and image cold-start times — significant in serverless.
Edge cases
- •Build-only deps (e.g. `tailwindcss`) belong in `devDependencies` for libraries but `dependencies` if a Next.js app needs them at *runtime* build (depends on platform).
- •Some hosting (e.g. Vercel) installs all deps regardless and runs build there — dev/runtime split still affects the runtime layer.
Real-world examples
- •Most React component libraries declare React as a peerDependency and put it in devDependencies for local development.
Senior engineer discussion
Senior signal: discuss peer-dep ranges, dependency hoisting in monorepos (pnpm strict vs npm flat), and how lockfile + omit=dev shape image security posture.
Related questions
Frontend
Easy
4 min