What does "tree shaking" do?
What Tree Shaking is
Tree shaking is the process of removing unused code from the final JavaScript bundle. The name literally translates as "shaking the tree" - imagine your project's code is a tree, and the extra, "dead" branches (functions, modules, imports) simply fall off during the build.
Less code -> faster loading -> better performance.
The idea in a nutshell
If some function, variable, or import is used nowhere, the bundler (for example, Webpack, Rollup, Vite) will remove that code from the final file.
Example without tree shaking
// utils.js
export function add(a, b) { return a + b; }
export function sub(a, b) { return a - b; }
export function mul(a, b) { return a * b; }
export function div(a, b) { return a / b; }
// main.js
import { add } from './utils.js';
console.log(add(2, 3));Without tree shaking, the bundler includes all functions (add, sub, mul, div) in bundle.js,
even though only add() is actually used.
With tree shaking
With tree shaking enabled (for example, in Webpack's production mode, Rollup, or Vite),
the final bundle contains only what is actually used - add().
As a result:
- the bundle size is smaller,
- loading is faster,
- parsing and running the code is faster.
How it works technically
Tree shaking is based on:
- ES Modules (ESM) -
import/export(unlikerequire, ESM imports are static and analyzed at build time); - static dependency analysis - the bundler knows which exports are actually used;
- removing "dead code" via "dead code elimination" optimization.
Example:
// static import -> the bundler sees that only add is used
import { add } from './utils.js';CommonJS (require), on the other hand, does not support tree shaking:
const utils = require('./utils'); // the bundler can't know for sure what's usedWhen tree shaking won't work
Tree shaking does not work if:
- you use CommonJS (
require) instead of ES Modules (import/export); - the code has side effects (for example, it runs on import);
- the library didn't set
"sideEffects": falseinpackage.json; - you write dynamic imports or access properties through variables.
Example with a side effect:
// side.js
console.log("This code runs on import!");
export const x = 42;Even if x is never used, the whole file won't be removed -
because importing it triggers a console.log(), that is, a side effect.
Settings in Webpack / Vite / Rollup
Webpack
Tree shaking is enabled automatically in production mode,
if package.json has:
{
"sideEffects": false
}(or a list of files that do have side effects)
Rollup
Tree shaking is enabled by default. Rollup was historically the first bundler to introduce it.
Vite / ESBuild
Works out of the box, since it's built on ESM and Rollup.
Example result
Before optimization:
bundle.js - 120 KBAfter tree shaking:
bundle.js - 42 KBSummary
| Point | Description |
|---|---|
| What it does | Removes unused code from the final bundle |
| Based on | ESM (import/export) and static analysis |
| Works in | Webpack, Rollup, Vite, Parcel |
| Doesn't work with | require(), side effects |
| Goal | Reduce size and speed up loading |
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.