What is tree shaking?
By FrontendPro Editorial Team Updated 9/26/2026
Answer
Tree shaking is dead-code elimination for JavaScript bundles. The bundler builds a graph of what each module exports and what is actually imported, then drops the exports nobody reached.
// utils.js
export function formatDate() { /* ... */ }
export function parseCsv() { /* ... */ } // huge, never used
// app.js
import { formatDate } from "./utils.js"; // parseCsv is shaken out
Why it needs ES modules
import/export are static: the bundler can see the whole dependency graph without running the code. CommonJS cannot be analysed the same way, because require() is a function call that may be conditional or computed:
const mod = require(someCondition ? "./a" : "./b"); // unanalysable
So a dependency shipped only as CommonJS usually lands in your bundle whole.
What stops it working
- Side effects. If a module changes something on import — patching a global, registering a component, importing a CSS file — the bundler must keep it, because removing it would change behaviour. Declare
"sideEffects": falseinpackage.json(or list the files that do have them) to tell it otherwise. - Importing everything.
import * as utils from "./utils"followed by dynamic access defeats the analysis. Named imports are what you want. - Re-export barrels. A big
index.jsre-exporting a whole library can pull in far more than you asked for, depending on the bundler.
Checking it worked
Do not assume. Build for production — tree shaking only runs with minification enabled — then inspect the output with rollup-plugin-visualizer, webpack-bundle-analyzer or source-map-explorer. Seeing a library you barely use taking 100 KB is usually a sign it is CommonJS-only or marked as having side effects.
