No dev dependencies serving production runtime roles
Why it matters
A runtime package in devDependencies will silently disappear when your deployment runs npm install --production or NODE_ENV=production — causing runtime crashes that only surface in production, not local development or CI. Conversely, build tools like jest, eslint, and typescript in dependencies bloat your production install, increase container image sizes, and expand the attack surface of your production environment with tooling that was never meant to be deployed. OWASP A06 applies when the wrong set of packages is present in the production environment. CWE-1357 covers unnecessary components in the production software composition. SSDF PW.4 requires that the production component set be intentionally defined and reviewed.
Severity rationale
High because a runtime package accidentally in devDependencies causes guaranteed production crashes when installed with `--production` or `NODE_ENV=production`, while build tools in dependencies silently expand production attack surface.
Remediation
Move packages to the correct section using the explicit save flags:
# Move a runtime package from devDependencies to dependencies
npm install package-name --save-prod
# Move a build tool from dependencies to devDependencies
npm install package-name --save-dev
For Next.js and similar SSR frameworks: dependencies should include any package imported in server-side code, API routes, or middleware — not just client-side imports. The --omit=dev flag in production installs skips devDependencies entirely, so anything imported at runtime must be in dependencies.
Detection
-
ID:
no-dev-in-prod -
Severity:
high -
What to look for: Examine
devDependenciesfor packages that should be independenciesbecause they are required at runtime. Red flags:dotenvin devDependencies when.envloading happens in production code, server framework packages (express,fastify,hono) in devDependencies, ORM packages (prisma,drizzle-orm) in devDependencies when the project has a database, auth packages (next-auth,@supabase/supabase-js) in devDependencies. Conversely, checkdependenciesfor packages that should be in devDependencies:jest,vitest,eslint,typescript,@types/*,prettier, test utilities. Having test frameworks independenciesinflates production install size. Count all instances found and enumerate each. -
Pass criteria: Development-only dependencies must not appear in the production dependency list. Check that testing frameworks, linters, formatters, type checkers, and build-only tools are listed under "devDependencies" rather than "dependencies" in the manifest. Production bundles should not include dev tooling that adds install time, attack surface, and deployment weight without contributing to runtime functionality. At least 1 implementation must be confirmed.
-
Fail criteria: A package required at production runtime is only in
devDependencies, or test/build tooling is independencies(not just devDependencies). -
Skip (N/A) when: No
package.jsondetected. -
Detail on fail:
"'dotenv' is in devDependencies but is used in production server initialization — move to dependencies"or"'jest' and 'vitest' are in dependencies — these are test frameworks and belong in devDependencies" -
Remediation: Misplaced dependencies cause two distinct problems: runtime packages in devDependencies cause production crashes when
NODE_ENV=productioninstalls skip devDependencies. Build tools in dependencies bloat your production install.Move packages to the correct section:
# Move a package from devDependencies to dependencies npm install package-name --save-prod # Move a package from dependencies to devDependencies npm install package-name --save-devFor Next.js, Nuxt, and similar frameworks that handle bundling:
dependenciesvsdevDependenciesdistinction is about what gets installed in CI/production environments, not about the bundle. Usedependenciesfor any package imported in server-side or API code.
External references
- cwe · CWE-1357 — Reliance on Insufficiently Trustworthy Component
- owasp:2021 · A06 — Vulnerable and Outdated Components
- ssdf:800-218 · PW.4 — Reuse Existing, Well-Secured Software
Taxons
History
- 2026-04-18·v1.0.0·Initial import from dependency-supply-chain·automated