Sometimes, but do not rely on it. Tree shaking removes unused exports from ES module code in a production build, so a vulnerable function you never import may not ship. It depends on module format and side effect settings, and the package stays vulnerable on disk and in your lockfile.
What tree shaking is
The webpack guide calls tree shaking a term commonly used for dead-code elimination in JavaScript. It relies on the static structure of ES2015 import and export syntax. If a module exports two functions and you import one, the other can be dropped from the production bundle.
When it does not help
| Situation | Effect |
|---|---|
| Package ships CommonJS only | Whole package tends to stay in the bundle |
| A compiler turns ES modules into CommonJS before bundling | Tree shaking is defeated, webpack warns that Babel's preset env does this by default |
| The vulnerable code runs at import time | It counts as a side effect and stays |
| Code you call is the vulnerable function | Obviously stays |
| Development builds | Unused exports are marked but not removed |
The sideEffects flag in package.json tells the bundler whether files do anything when merely imported. Set it wrongly and you can drop needed code, such as CSS imports. Leave it out and the bundler stays cautious and keeps more.
Why it is not a security control
- Tree shaking is an optimization. It is not tested or promised as a way to remove flaws.
- The result changes with bundler version, config and package updates.
- Advisories are filed against package versions. Your scanner will flag the package whether or not the function ships, and an auditor will ask for the upgrade.
- Server side or build time use of the same package is unaffected.
- A vulnerable path may be reachable through a function you do call, even indirectly.
So treat tree shaking as a reason a finding may be lower risk, not a reason to ignore it.
How to check what really shipped
- Build in production mode and open the output or a bundle analyzer report to see whether the package is present.
- Search the output for a distinctive string from the vulnerable function.
- Compare against the advisory, which usually names the affected function or feature.
- Record the result next to the finding with a date, so the decision is traceable.
A sensible policy
Upgrade anyway when a fix exists. If you cannot upgrade soon, document the evidence that the vulnerable code is not shipped and not reachable, and set a date to revisit. Reachability analysis does this at the call graph level and is more reliable than guessing from bundle size. See scan the lockfile or the built bundle.
Safeguard offers reachability analysis and dependency scanning, with a free scan at gold.safeguard.sh/scan.
Try it yourself
Click through it at your own pace, or open it full screen. Compare the full finding list with the reachable one.
Quick check
If the function is tree shaken out, can I skip the upgrade?
You can lower the priority with evidence, but the package version is still flagged and the next change to your code could pull it back in.
Does minification remove unused code?
Minifiers shrink code and can remove some dead statements, but removing whole unused exports is the job of tree shaking, which needs ES module syntax.
Sources
- webpack, Tree Shaking guide: https://webpack.js.org/guides/tree-shaking/
Last reviewed: 19 October 2026.