2 min read

Tree Shaking

Tree shaking is a term commonly used in the JavaScript context for dead-code elimination. It relies on the static structure of ES6 module syntax (import and export) to detect and remove unused code from the final bundle.

1. The Concept

Imagine your application as a tree. The code you actually use represents the green, living leaves. The dead code (unused exports) represents brown, dead leaves. "Shaking" the tree makes the dead leaves fall off.

In technical terms, the bundler (like Webpack or Rollup) analyzes your dependency graph and includes only the parts of the code that are explicitly imported and used.

2. Why ES6 Modules?

Tree shaking works best with ES6 modules because they are static.

  • You can only import/export at the top level.
  • You cannot import conditionally inside a function.
  • The bundler can determine at compile time exactly which exports are used without running the code.

CommonJS is dynamic:

// CommonJS - Hard to tree shake
const myModule = require(condition ? './a' : './b');

Because the import depends on runtime evaluation (condition), the bundler cannot safely exclude code.

3. Example

math.js

export function add(a, b) {
  return a + b;
}

export function subtract(a, b) {
  return a - b;
}

main.js

import { add } from './math.js';

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

When this code is bundled with tree shaking enabled:

  1. The bundler sees that add is imported and used.
  2. It sees that subtract is exported but never imported.
  3. It drops the subtract function from the final output bundle, reducing the file size.

4. Side Effects

A "side effect" is code that performs a special behavior when imported, other than exposing exports (e.g., modifying a global variable, adding a polyfill, or applying CSS).

If a module has side effects, the bundler cannot safely remove it even if its exports aren't used, because removing it might break the app.

sideEffects: false

You can tell bundlers (like Webpack) that your package or specific files contain no side effects via package.json.

{
  "name": "my-library",
  "sideEffects": false
}

This allows the bundler to aggressively remove any unused imports from your library.

programming/javascript/vanilla/javascript programming/javascript/vanilla/es6-vs-commonjs programming/javascript/vanilla/modules