Every major ecosystem lets you mark some dependencies as not part of the shipped product, but the mechanism and the default differ. Maven uses scopes, npm can omit dev packages, Cargo has a separate build-dependencies section, and NuGet uses private assets. Know which one your project uses, or reports will mix shipped and non-shipped code.
Why it matters
A vulnerability in a test framework is not the same as one in a library inside your container. If your report treats them alike, teams lose trust and start ignoring findings. If your report hides all dev dependencies, you miss risks that run on build agents, where credentials live.
The right answer is to separate the two and still watch both.
The mechanisms
| Ecosystem | How non-shipped dependencies are marked | Key detail from the docs |
|---|---|---|
| Maven | Scope: test, provided, runtime, compile | Test and provided scopes are not transitive |
| npm | Dev dependencies, omitted with the omit option | Omitted packages are still resolved and recorded in the lockfile |
| Cargo | A separate build-dependencies section | Separate from the package's normal dependencies |
| NuGet | PrivateAssets and IncludeAssets metadata | Private assets are consumed but do not flow to the parent project |
Maven
The Maven guide defines compile as the default scope, available in all classpaths and propagated to dependents. Provided means the JDK or a container supplies it at runtime, and it is not transitive. Test is only available for test compilation and execution, and is not transitive. Runtime is not needed for compilation but is for execution.
npm
The audit docs say that the omit option leaves named dependency types out of the on-disk installation, yet omitted packages are still resolved and recorded in the lockfile. It defaults to dev when NODE_ENV is production. With the quick audit endpoint, omitted types are skipped when building the report.
Cargo
Build dependencies are declared in their own section. They are what a build script needs, and build scripts run before the package is built. This is the group that executes on your build machine.
NuGet
PrivateAssets controls which assets of a dependency flow to a parent project. The default private assets are contentfiles, analyzers and build. A package marked as a development dependency in its nuspec is kept out of other packages' dependency lists.
What this means for scanning
- Scan everything, then label each component with its scope.
- Report shipped components first, since those reach customers.
- Keep a second view for build time components, since they reach your pipeline.
- Do not silently drop a class just because it is labeled dev.
Keep the label as data on each component, so you can filter views without losing anything.
A caution on labels
Labels are declared by the project, not verified by the registry. A package can be declared dev and still be bundled by a build step. When the shipped artifact matters, scan that artifact too.
Safeguard can help here: it scans dependencies and generates SBOMs, applies reachability analysis so you can sort findings by what your code can actually call, and enforces policies and gates on pull requests. You can try a free scan on a repository to see what it finds.
Quick check
Are dev dependencies safe to ignore?
No. They do not ship, but they run on developer machines and CI agents. Rank them lower for customer impact, not zero.
Does the npm omit option change the lockfile?
Per the npm docs, omitted packages are still resolved and recorded in the lockfile. Omit affects what is installed on disk.
Sources
Last reviewed: 19 October 2026.