Understanding Tree Shaking

@vineetpjp|12,543 views

Tree shaking is one of the most important optimization techniques in modern JavaScript bundling. The term was popularized by Rollup, though the concept of dead code elimination has existed for decades.

At its core, tree shaking is about removing unused code from your final bundle. The name comes from the mental model of shaking a tree — the dead leaves (unused code) fall away, leaving only the healthy branches (code you actually use).

How It Works

Tree shaking relies on the static structure of ES6 module syntax. Unlike CommonJS's dynamic require(), ES6's import and export statements are static, meaning they can be analyzed at build time without executing the code.

Consider this example:

// utils.js
export function add(a, b) {
  return a + b;
}

export function multiply(a, b) {
  return a * b;
}

// main.js
import { add } from './utils.js';

console.log(add(2, 3));

A bundler with tree shaking will detect that multiply is never imported and will exclude it from the final bundle. This works because the bundler can statically analyze the import/export relationships.

Why CommonJS Can't Be Tree Shaken

CommonJS modules use require() and module.exports, which are dynamic. You can conditionally require modules, compute module paths at runtime, or assign to module.exportsanywhere in your code:

// This can't be statically analyzed
const moduleName = condition ? './moduleA' : './moduleB';
const myModule = require(moduleName);

Because the bundler can't know which code will actually be used without running the program, it must include everything.

Best Practices

  • Always use ES6 module syntax (import/export) in your source code
  • Avoid side effects in modules, or mark them explicitly with sideEffects in package.json
  • Use named exports rather than default exports for better tree shaking
  • Configure your bundler properly — different tools have different defaults

Modern Bundlers

Today, most major bundlers support tree shaking: Webpack (with production mode), Rollup (enabled by default), esbuild, and Vite. However, the effectiveness varies. Rollup generally produces the smallest bundles, while Webpack requires more configuration.

Understanding tree shaking is essential for building performant web applications. Every kilobyte you eliminate from your bundle is one less kilobyte users need to download, parse, and execute.