Tree shaking in Node.js: An In-Depth Guide for Senior Developers
Tree shaking is a term used in modern JavaScript bundlers (most notably Webpack, Rollup, esbuild, Vite, and Parcel) that refers to the process of eliminating unused ("dead") code from the final bundle during the build process.
The name "tree shaking" comes from the idea of vigorously shaking a tree to make all the dead leaves (unused code) fall off, leaving only the living parts.
Key Concept: Static Analysis + ES Modules
Tree shaking works effectively only when certain conditions are met:
| Condition | Required for Good Tree Shaking? | Explanation |
|---|---|---|
ES Modules (import/export) | Yes (strongly recommended) | Only ESM allows reliable static analysis |
| Side-effect-free modules | Yes | Module must not have global side effects when imported |
sideEffects: false in package.json | Highly recommended | Explicit hint to bundlers that module is safe to tree-shake |
| Production mode | Usually required | Many bundlers disable tree shaking in development mode |
| No dynamic imports for the code | Helpful | import() can sometimes prevent shaking |
No CommonJS (require/module.exports) | Strongly preferred | CommonJS is much harder/impossible to reliably tree-shake |
Classic Example
// math.js
export function add(a, b) {
return a + b;
}
export function subtract(a, b) {
return a - b;
}
export function multiply(a, b) {
console.log("I'm expensive!");
return a * b;
}// main.js
import { add } from "./math.js";
console.log(add(5, 3));Result after tree shaking (production build):
// Only this remains in the bundle
function add(a, b) {
return a + b;
}
console.log(add(5, 3));subtract and multiply are completely removed because they were never used.
How to Maximize Tree Shaking Effectiveness (2025-2026 Best Practices)
- Use ES Modules everywhere (avoid CommonJS when possible)
- Add this to your package.json:
{
"sideEffects": false
}Or more precisely (recommended today):
{
"sideEffects": ["*.css", "*.scss", "*.less", "*.vue", "*.stories.tsx"]
}- Prefer named exports over default exports when possible
- Avoid code with unavoidable side effects at module top-level
- Use production builds (
mode: "production"in webpack/vite/rollup) - Prefer libraries that are tree-shakeable (many modern libraries are)
Quick Comparison - Tree Shaking Friendliness (2025)
| Library/Pattern | Tree-shaking Quality | Notes |
|---|---|---|
| lodash-es | Excellent | Designed specifically for tree shaking |
| date-fns | Excellent | Individual function imports |
| old lodash (commonjs) | Poor | Almost no tree shaking |
| class-based components + methods | Medium-Poor | Methods are hard to shake |
| React + named imports | Good-Excellent | Modern patterns work very well |
| Barrel files (index.js re-exports) | Can be harmful | Can prevent shaking if not careful (use sideEffects: false) |
In summary: Tree shaking is one of the most powerful size-optimization techniques available in the modern JavaScript ecosystem, but it relies heavily on using ES Modules correctly and providing proper side-effects hints to the bundler.
When done right, it can easily reduce bundle size by 30-70% compared to non-optimized builds.
Last updated on