Skip to main content
JavaScript & the browser·Module C3 · Lesson 5
TaskInline approximation: declare an inline 'utils' object with three methods (add, sub, mul). Use a NAMED-import-style destructure to pull only 'add' out of utils. Log add(2,3) — expect 5.

Tree-shaking: why named imports beat namespace imports

75 XP7 min
Theory

What tree-shaking does

A bundler walks your import graph and drops any export your code doesn't reference. The "tree" is your module graph; the "shake" is unused leaves falling off. End result: smaller bundles.

What kills tree-shaking

import * as lodash from "lodash";    // imports ALL of lodash, no shake
lodash.debounce(fn, 100);

vs.

import { debounce } from "lodash";   // bundler can drop everything else
debounce(fn, 100);

The namespace import import * as X forces the bundler to keep every exported symbol — you might reference X.anything at runtime, it can't know.

The other killer: side effects

// some-pkg/index.js
import "./polyfill.js";    // side-effect import — runs the file even if you import nothing

If a package's entrypoint runs code at import time, that code stays in your bundle even if you only used one export. package.json has "sideEffects": false to declare a library is side-effect-free; bundlers honour it.

Two practical rules

  1. Always use named imports unless the library forces a namespace.
  2. Prefer libraries that mark "sideEffects": false and only use ESM.

In 2026 nearly every modern library does this (lodash-es, date-fns, ramda). It's CommonJS-only libraries (the older Node-style module.exports) that still bloat bundles by default.

🔒

Sign up to start coding

Theory is open to everyone. The interactive editor, live preview, and check are unlocked with a 7-day free trial — card required, cancel anytime.

Sign up — free trial →

First 10 lessons in each track are free. No card needed for those.

PreviousNext lesson →

Get one Python or web tip a day — by email

Short, hand-written, no spam. Unsubscribe in one click.