Guide
Diagnosing Rollup Tree‑Shaking Failures: A Practical Checklist
Spot and fix Rollup tree‑shaking failures that leave unused code in your bundle. Follow a step‑by‑step diagnostic checklist, example config, and verification steps to reduce bundle size.
Published by Tasadduq Burney
20 Jan 2026, 03:23 UTC
3 min43.8K views0

Recognizable Condition
After a production build you notice the bundle is larger than expected, or a source‑map shows code that your application never calls (e.g., lodash helpers or internal utilities). The bundle also contains /* @__PURE__ */ annotations that should have been stripped. This indicates Rollup’s tree‑shaking did not eliminate unused exports.
Common Causes – Quick Reference
| Cause | Typical Symptom |
|---|---|
Missing @rollup/plugin-commonjs or wrong order | Whole CommonJS modules appear in the bundle; named exports are not recognized. |
Exporting via module.exports or export = | Module is treated as side‑effect only; no tree‑shaking. |
Incorrect output.exports mode | Rollup cannot determine which exports are used; falls back to keeping everything. |
Package.json sideEffects mis‑configured | Side‑effect flags prevent removal of code even if unused. |
Missing or overridden /* @__PURE__ */ annotations | Helper functions remain in the bundle. |
Ordered Checks
- Verify the CommonJS plugin
Runnpm ls @rollup/plugin-commonjsto ensure it is installed. Inrollup.config.jsconfirm it appears before other plugins that transform the code. - Inspect plugin order
The order of plugins matters.commonjsmust run beforeterseror any custom plugin that relies on ES module syntax. - Run Rollup in debug mode
Execute
Look for warnings such asrollup -c --debugTreating … as externalorSkipping module … because it is marked as side‑effect only. - Check package side‑effects
Open thepackage.jsonof each third‑party module you depend on and look for\"sideEffects\": falseor an array. If the array lists files that contain side effects, Rollup will keep them. - Validate export syntax
Search your source forexport =,module.exports, orexport defaultthat is used where named exports are expected. Useexport function foo()orexport const bar = …instead.
Fixes Tied to Findings
- Add or reposition
@rollup/plugin-commonjs
Inrollup.config.js:import commonjs from '@rollup/plugin-commonjs';\ export default {\n input: 'src/main.js',\n plugins: [\n commonjs(), // before other plugins\n // ...\n ],\n}; - Define named exports for opaque libraries
If a library like lodash is imported as CommonJS and Rollup cannot infer named exports, add anamedExportsmap:commonjs({\n namedExports: {\n lodash: ['map', 'each']\n }\n}); - Adjust
output.exportsmode
For pure ES modules, setoutput.exports = 'named'to allow Rollup to track named usage. - Mark libraries as side‑effect‑free
If a dependency truly has no side effects, add\"sideEffects\": falseto itspackage.jsonor override in your own config viasideEffects: falsein theexternalfield. - Refactor imports to ES syntax
Replacerequire('foo')withimport foo from 'foo'where possible. This ensures Rollup treats the module as ES and can tree‑shake.
Verification Steps
- Build with
--silent
rollup -c --silent - Analyze the bundle
Runnpm i -D rollup-plugin-visualizerand add it to the plugins list:
The generated HTML shows a tree of modules; verify the suspect code is absent.import visualizer from 'rollup-plugin-visualizer';\nplugins: [\n // ... other plugins\n visualizer({ open: true })\n]\n - Compare gzipped sizes
Usegzip -c dist/bundle.js | wc -cbefore and after the fix. A 5‑10 % reduction is a good indicator that tree‑shaking succeeded. - Check console warnings
Re‑run with--debugand confirm no “treating … as external” warnings for the modules in question.
Escalation Criteria
If after applying all fixes the bundle remains larger than expected, consider:
- Opening an issue on the plugin’s repository with a minimal reproducible example; include the config and the console output.
- Enabling the experimental
--experimentalOptimizeChunksflag to see if it improves the situation. - Manually externalizing the problematic module by adding it to the
externalarray in the config and verifying the size drop. - Contacting the library maintainer to request a
sideEffectsupdate if the library incorrectly marks files as side‑effect‑free.
Practical Checklist Summary
- Confirm
@rollup/plugin-commonjsis present and correctly ordered. - Validate
output.exportsmode. - Inspect third‑party
sideEffectsflags. - Ensure exports use ES named syntax.
- Run visualizer and compare sizes.
- If unresolved, file a minimal issue or externalize the module.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.