What is Tree Shaking?

Tree shaking is dead code elimination for JavaScript.

It relies on the import and export statements to detect if code modules are exported and imported for use between JavaScript files.

In modern JavaScript applications, we use module bundlers (e.g., webpack or Rollup) to automatically remove dead code when bundling multiple JavaScript files into single files reducing size and improving load time.


<aside> 💡

What is Dead Code?

Dead code = code that exists in your source but is never executed in the final app.

Examples:

📚How bundlers perform tree-shaking:

  1. Parse to AST: Code is transformed into an Abstract Syntax Tree (AST), a hierarchical, structured representation that the bundler can understand.
  2. Build Dependency Graph: The bundler analyzes the ASTs of all modules to map out:
  3. Mark Used Exports: Starting from the application's entry points (e.g., index.js), the bundler traverses the dependency graph. Any export that is actually imported and used is marked as "live" or "used."
  4. Remove Unused Exports: After marking, any code (functions, variables, classes) that was not marked as "used" is then removed from the final bundle. This can happen:

Stay tuned, I’ll be covering code splitting in one of the next articles.


Why Import Type Matters

Tree shaking only works reliably with ES Modules (ESM):

Feature ESM (import/export) CommonJS (require/module.exports)
Static imports/exports ✅ Yes ❌ No (dynamic)
Top-level only ✅ Yes ❌ No
Immutable exports ✅ Yes ❌ No (can mutate at runtime)
Static analysis friendly ✅ Yes ❌ No
Tree shaking works well ✅ Yes ⚠️ Limited

Example — ESM (Tree Shakable)

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

// index.js
import { add } from "./math.js";
console.log(add(2, 3));