Skip to main content

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

javascript
// 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:

  1. ES Modules (ESM) - import / export (unlike require, ESM imports are static and analyzed at build time);
  2. static dependency analysis - the bundler knows which exports are actually used;
  3. removing "dead code" via "dead code elimination" optimization.

Example:

javascript
// 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:

javascript
const utils = require('./utils'); // the bundler can't know for sure what's used

When 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": false in package.json;
  • you write dynamic imports or access properties through variables.

Example with a side effect:

javascript
// 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:

javascript
{ "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:

javascript
bundle.js - 120 KB

After tree shaking:

javascript
bundle.js - 42 KB

Summary

PointDescription
What it doesRemoves unused code from the final bundle
Based onESM (import/export) and static analysis
Works inWebpack, Rollup, Vite, Parcel
Doesn't work withrequire(), side effects
GoalReduce size and speed up loading

Short Answer

Interview ready
Premium

A concise answer to help you respond confidently on this topic during an interview.