Remove Unused Exports from Browser Bundles with Rollup
Configure Rollup tree-shaking to remove unused ES module exports from browser bundles, with a worked example and verification steps.
06 Sept 2026, 18:13 UTC

Your browser bundle may include code you never call
If you import a single helper from a utility module, a naive bundler can still ship every function in that module. Those unused exports add parsing and download time for no runtime benefit.
Rollup removes unused exports through static analysis
Rollup parses import and export statements at build time. If an export is never imported by the entry point or any kept module, Rollup can omit that declaration and any side-effect-free code that only supports it. This works best when both input and output use ES module formats, such as es or iife. CommonJS output makes elimination harder because require calls are dynamic and difficult to analyze statically.
Tree-shaking is distinct from minification. Rollup removes unused exports; a minifier such as Terser later removes dead code inside the modules that remain.
Worked example: bundle one function, drop the rest
Create src/math.js with one used export and one unused export:
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export function unusedHelper() {
return "this should disappear";
}
Create src/main.js that imports only add:
import { add } from "./math.js";
console.log(add(2, 3));
Add rollup.config.js in the project root:
export default {
input: "src/main.js",
output: {
file: "dist/bundle.js",
format: "iife",
name: "app",
},
treeshake: {
moduleSideEffects: false,
},
};
Run the build from the project directory. No special permissions are required beyond write access to the project folder:
npx rollup -c rollup.config.js
Check whether the unused function survived:
grep -n "unusedHelper" dist/bundle.js || echo "unusedHelper not found"
If tree-shaking worked, unusedHelper does not appear in dist/bundle.js, while add remains. You can confirm the kept function with:
grep -n "function add" dist/bundle.js
Limitations and verification steps
- Not guaranteed. Transitive dependencies, dynamic
import(), andeval-like patterns can keep code in the bundle. - Side-effect contract. Setting
sideEffects: falseinpackage.jsontells Rollup a module has no side effects. If the module actually mutates global state or relies on import-time execution, removing unused imports can break runtime behavior. - Format matters. Prefer
esoriifeoutput for the most reliable elimination. CommonJS output can limit what Rollup removes. - Version differences. Behavior can differ between Rollup major versions and plugin configurations. Check the documentation for your installed version.
Practical check: build the same entry twice, once with treeshake enabled and once disabled, then compare file size and search the output for unused export names. Finally, run the bundle in a browser or Node smoke test to confirm the imported function still works after unused exports are removed.
Closing
Start with a small entry file and a local module, verify that unused exports disappear from the output, then apply the same configuration to your application bundle. Treat sideEffects: false as a contract, not an optimization flag, and always smoke-test after enabling tree-shaking.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.