Every runtime dependency you ship is inherited by every consumer. lodash (full) adds ~72KB minified; moment adds ~230KB. A focused SDK with full lodash as a runtime dependency imposes that weight on every browser bundle that installs it — directly increasing page load times and Lighthouse performance scores for users who never touch the offending methods. ISO 25010 resource-utilization flags this; SLSA L1 supply chain concerns apply because each runtime dependency is an additional attack surface. CWE-1357 covers use of unnecessarily broad software components.
High because bloated runtime dependencies inflate every consumer's install size and bundle weight, and each transitive dependency expands the supply chain attack surface.
Audit runtime dependencies and replace heavy packages with built-in alternatives or lighter substitutes.
// Before — heavy runtime deps:
{
"dependencies": {
"lodash": "^4.17.0",
"axios": "^1.0.0",
"moment": "^2.29.0"
}
}
// After — zero runtime deps:
{
"dependencies": {}
}
// Replace lodash.get with optional chaining:
// Before: _.get(obj, 'a.b.c', defaultVal)
// After: obj?.a?.b?.c ?? defaultVal
// Replace axios with built-in fetch (Node 18+):
// Before: const { data } = await axios.get(url)
// After: const data = await fetch(url).then(r => r.json())
Run npx bundlephobia-cli <package-name> before adding any new runtime dependency. Target: published package under 500KB gzipped.
ID: sdk-package-quality.build-distribution.bundle-size
Severity: high
What to look for: Count all files included in the published package. examine dependencies in package.json for packages that are disproportionately large relative to their utility:
lodash (full) instead of individual lodash.* packages or lodash-esmoment instead of date-fns or dayjsaxios when fetch (built-in) would sufficeaws-sdk (v2, 70MB+) instead of @aws-sdk/* (v3 modular)dependencies — more than 10 is a yellow flag for a focused library.Pass criteria: Runtime dependencies are minimal and appropriately sized. No obviously bloated packages when lighter alternatives exist. Total dependency count is reasonable for the package's scope — published package must be under 500 KB gzipped for typical SDK usage. Report even on pass: "Published package size: X KB (Y files)."
Fail criteria: One or more runtime dependencies are known to be disproportionately large (e.g., full lodash when only get is used), OR the package has more runtime dependencies than its scope justifies (e.g., 15 dependencies for a string utility library).
Skip (N/A) when: The package has zero runtime dependencies. Also skip for Go (vendoring is different) and Rust (cargo handles dependency sizes differently).
Detail on fail: "5 runtime dependencies including lodash (full, 72KB minified) — only lodash.get is used. Replace with optional chaining (?.) or lodash-es for tree-shaking. Also includes axios when the built-in fetch API would suffice."
Remediation: Your consumers inherit your dependency tree. Every dependency you add increases their install size, build time, and supply chain risk.
// Before — heavy dependencies:
{
"dependencies": {
"lodash": "^4.17.0",
"axios": "^1.0.0",
"moment": "^2.29.0"
}
}
// After — minimal or none:
{
"dependencies": {}
}
// Replace lodash.get with optional chaining:
// Before: _.get(obj, 'a.b.c', defaultVal)
// After: obj?.a?.b?.c ?? defaultVal
// Replace axios with fetch:
// Before: const { data } = await axios.get(url)
// After: const data = await fetch(url).then(r => r.json())