No large unused dependencies in bundle
Why it matters
Unused production dependencies are dead weight with live consequences: they bloat the bundle, slow install times, expand the attack surface, and create maintenance debt for packages that will never receive targeted security updates. moment (60KB gzipped), full lodash (70KB gzipped), and date-fns without tree-shaking are common culprits found installed for a single date formatting call. Beyond bundle size, ISO 25010 performance-efficiency.resource-utilization counts every unnecessarily included module as a resource waste — and npm audit flags transitive vulnerabilities in packages you don't actually use.
Severity rationale
Medium because unused large dependencies directly add payload to the bundle and expand the vulnerability surface area, even when the package itself works correctly.
Remediation
Audit production dependencies against actual import usage. Remove packages that are never imported; replace heavy packages that are used for a single function with a lighter alternative or native implementation.
# Identify unused dependencies
npx depcheck
# Remove confirmed-unused packages
npm uninstall moment lodash
// Before — 60KB for one function
import moment from 'moment'
const formatted = moment(date).format('YYYY-MM-DD')
// After — native, zero bytes added
const formatted = new Date(date).toISOString().slice(0, 10)
// Or tree-shakeable alternative
import { format } from 'date-fns'
const formatted = format(date, 'yyyy-MM-dd')
// Before — 70KB lodash for one utility
import _ from 'lodash'
const result = _.debounce(fn, 300)
// After — tree-shakeable import
import debounce from 'lodash-es/debounce'
Detection
-
ID:
no-unused-dependencies -
Severity:
medium -
What to look for: Count all production dependencies in
package.json. For each dependency over 50KB (bundled size estimate), search source files for actual import statements. Classify each as: (a) fully used, (b) partially used (only 1-2 functions imported from a large library), or (c) unused (listed in package.json but never imported). Enumerate: "X production dependencies, Y actually imported, Z unused or partially used." -
Pass criteria: No more than 1 production dependency is completely unused (listed but never imported). No more than 2 large libraries (over 50KB bundled) are partially used with less than 10% of their API surface consumed. Report: "X of Y production dependencies are actively imported in source code."
-
Do NOT pass when: A dependency like
lodashormomentis imported in only 1 file using 1 function — this is a large unused dependency even if technically "imported." -
Fail criteria: 2 or more large production dependencies (lodash, moment, date-fns without tree-shaking) are installed but unused, or only a small fraction of their functionality is used.
-
Skip (N/A) when: Never — unused dependencies bloat the bundle.
-
Detail on fail:
"3 of 18 production dependencies are unused — lodash (70KB), moment (60KB), and classnames (5KB) are listed but never imported"or"moment imported in 1 file for 1 function — 60KB added to bundle for Date.now() equivalent" -
Remediation: Remove unused dependencies and use tree-shakeable alternatives:
# Find unused dependencies npm prune npm ls — unused (npm@v7+) # Remove unused packages npm uninstall lodash moment// Before — heavy dependencies import _ from 'lodash' import moment from 'moment' // After — lighter alternatives import { debounce } from 'lodash-es' // tree-shakeable import { formatDate } from 'date-fns' // small by default // Or use native utilities const debounce = (fn, delay) => { /* ... */ }
External references
- iso-25010:2011 · performance-efficiency.resource-utilization — Resource Utilization
Taxons
History
- 2026-04-18·v1.0.0·Initial import from performance-load·automated