Safeguard
Developer Tools•

Does an npm SBOM include devDependencies?

By default npm omits dev dependencies only when NODE_ENV is production. Learn how the omit setting shapes your SBOM and how to produce a runtime only file.

Safeguard Security Team
4 min read

It depends on your environment. The omit setting defaults to dev only when the NODE_ENV environment variable is set to production, and otherwise it is empty, so dev dependencies are included. To get a runtime only SBOM, omit dev explicitly instead of relying on the environment.

What the documentation says

The npm documentation for the omit setting says it defaults to dev if NODE_ENV is production, otherwise empty. It accepts dev, optional and peer, and can be set more than once. It also notes that omitted dependencies are still resolved and recorded in package-lock.json, but are not physically installed on disk.

The dedicated CycloneDX npm tool has the same option, with the same default behaviour tied to NODE_ENV.

That wording matters. Two people running the same command on the same repository can get different files, only because one shell has NODE_ENV set.

Why this changes your SBOM

A development dependency is a package your project needs to build or test but does not ship, such as a bundler, a linter or a test runner. Including them makes the SBOM describe your build environment. Leaving them out makes it describe the shipped application.

Neither is wrong. They answer different questions.

GoalDev dependencies
Customer facing file for a shipped appUsually omit
Internal inventory for build securityInclude
Library published to a registryDecide with consumers in mind

Be careful with the second row. Build tools run code on your developers' machines and in CI, and a compromise there can reach production. Excluding them everywhere leaves a blind spot.

Steps to produce each file

  1. Decide the purpose of the file and write it down.
  2. For a runtime file, set omit to dev in the command or the project configuration, so the result does not depend on NODE_ENV.
  3. For an internal file, make sure omit is empty and that your install step did not leave out dev packages.
  4. Name the files differently, for example with a suffix that says runtime or full.
  5. Compare the two and confirm the difference is the dev tree.

A trap with lockfile only mode

The package-lock-only setting makes the command use the lockfile and ignore node_modules. The npm documentation notes this means information from the package.json files of your dependencies, such as description, homepage and engines, will not be included. The dedicated tool says the same: output is then based on the few details in the lockfile. That affects richness of metadata, not the question of dev dependencies, but the two settings interact, so test your exact combination.

Another trap in the install step

If your CI installs with production settings, the dev packages never reach disk. An SBOM generated from the installed tree then lacks them even when you did not ask to omit them. If you want the full inventory, generate it from a full install or from the lockfile.

What to do with the result

Dev only findings are real but lower priority than runtime ones, since they do not execute in production. Safeguard's reachability analysis helps you separate vulnerable code your application calls from code it never reaches, and the free scan can show the difference on your own project.

Quick check

How do I make sure dev packages are left out?

Set the omit option to dev explicitly rather than relying on NODE_ENV, then check the component list for a known dev tool.

Are omitted packages gone from package-lock.json?

No. The documentation says they are still resolved and recorded in the lockfile, only not installed on disk.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.