Back
Web Fundamentals

Tree Shaking: Eliminate Dead Code from Your Bundle

Web Fundamentals
Build & Deployment: Monorepo, CI/CD, Strategies & Release SafetyState Management: Choosing the Right SolutionRedux: Predictable State Container (RTK + RTK Query)React Query (TanStack Query): Server State CachingData Fetching Patterns: REST, GraphQL, tRPC & Real-timeGraphQL Fundamentals for Frontend: Shape, Caching, and TradeoffsgRPC-Web Fundamentals: Browser Constraints and Proxy ModelCaching Strategies: Client, Server & EdgeData Normalization: Organizing State for PerformanceAPI Design Best Practices: Pagination, Errors, Versioning & Type SafetyAPI Versioning Strategies for Frontend CompatibilityPagination: Offset vs Cursor-BasedRate Limiting & API Resilience: Retries, Backoff, Jitter, IdempotencyHow Frontend Developers Can Handle Millions of API Requests Without Crashing EverythingBrowser Storage: Cookies, SessionStorage, LocalStorage, IndexedDBReal-time Communication: WebSockets, SSE & PollingWebRTC: Real-Time Communication in the BrowserCore Web Vitals: LCP, INP & CLSPerformance Optimization Trade-offsCritical Resource Prioritization: Optimize Loading OrderCode Splitting: Optimize Bundle Size with Dynamic ImportsTree Shaking: Eliminate Dead Code from Your BundleLazy Loading: Load Resources On-DemandResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip and BrotliImage & Video Optimization: Modern Formats & TechniquesAdaptive Loading: Optimize for Device & NetworkList Virtualization: Render Large Lists EfficientlyWeb Workers vs Main Thread: Offloading Heavy WorkMemory Leaks in Frontend Apps: Detection & PreventionManaging Third-Party Scripts: Optimization StrategiesHow CDNs Work: Edge Delivery, Caching & PerformanceHTTP Caching Deep Dive: Cache-Control, ETag & RevalidationService Workers & Offline Strategy: Cache First, Network First & Update LifecyclePWA Fundamentals: Manifest, Installability & Offline UXCritical Rendering PathScript Loading: async vs deferEvent Loop: Understanding JavaScript Execution ModelJavaScript Module Systems: CJS vs ESM vs UMDDynamic Module Loading: import() FunctionImport on Interaction: Load When User InteractsImport on Visibility: Lazy Loading with IntersectionObserverBrowser Rendering Pipeline & Layout ThrashingRendering Strategies: CSR vs SSR vs SSG vs ISRStreaming SSR: Progressive HTML StreamingIslands Architecture: Independent Component HydrationReact Server Components: Zero-JS Server RenderingFramework Reactivity: React, Vue, Svelte & SolidHTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC) for Frontend PerformanceDNS Resolution: Path, TTL, Caching & Frontend ImpactCross-Site Scripting (XSS) AttacksCross-Site Request Forgery (CSRF) AttacksCORS Explained: Cross-Origin Resource SharingCORS Preflight in Practice: Credentials, Simple Requests & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? Understanding TLS/SSLAuthorization Best PracticesCookie Security & Session Hardening: SameSite, HttpOnly, Secure
easyPerformance

Tree Shaking: Eliminate Dead Code from Your Bundle

TL;DRUse ES modules + named imports + sideEffects: false. Only ship code that is actually used.
High Signal
Google
Meta
Netflix
Agoda
Meesho
30-Second Answerstart every interview with this

Tree shaking is a build-time optimization where bundlers (Webpack, Vite, Rollup) automatically remove unused exports from your JavaScript bundles. It relies on static analysis of ES6 module syntax and proper configuration to maximize reduction in bundle size.

You tell the packer exactly what you need (named imports). The packer looks at your list and only puts those items in the suitcase. Anything you didn't explicitly ask for (unused exports) gets left behind — saving space and weight.

Import Statement (What you need)
Bundler Static Analysis
Mark Unused Exports
Remove Dead Code
Smaller Final Bundle

1How Tree Shaking Works

Bundlers perform static analysis on ES6 import/export syntax to determine which exports are used. Unused code is eliminated during the build process.

utils.tsts
export function add(a: number, b: number) { return a + b; }
export function subtract(a: number, b: number) { return a - b; }

// Only add is imported → subtract is removed

2Writing Tree-Shakeable Code

Use ES modules, named exports, avoid side effects, and prefer libraries designed for tree shaking (lodash-es, date-fns).

3Package Configuration

Mark packages as side-effect-free with `"sideEffects": false` in package.json. Use the `module` or `exports` field for modern bundlers.

4Verification

Use webpack-bundle-analyzer or Vite's visualizer to inspect what actually ends up in your final bundle.

PropertyTree-ShakeableNot Tree-Shakeable
ImportsNamed ES6 importsDefault / require() / import *
Librarieslodash-es, date-fnslodash, moment.js
SideEffects"sideEffects": falseSide effects present
Bundle ImpactMinimal (only used code)Large (entire library)

Tree-Shakeable

Imports

Named ES6 imports

Libraries

lodash-es, date-fns

SideEffects

"sideEffects": false

Bundle Impact

Minimal (only used code)

Not Tree-Shakeable

Imports

Default / require() / import *

Libraries

lodash, moment.js

SideEffects

Side effects present

Bundle Impact

Large (entire library)

Common questions

  • ›“What is tree shaking and how does it work?”
  • ›“How do you make your code tree-shakeable?”
  • ›“Why is lodash-es better than lodash?”
  • ›“How do you verify tree shaking is working?”

What interviewers look for

  • Understanding of ES modules vs CommonJS
  • Knowledge of sideEffects and named exports
  • Practical library choices and configuration
  • Verification techniques (bundle analyzer)

Short answer (60 sec)

Tree shaking removes unused code at build time using static analysis of ES6 modules. Use named imports, avoid side effects, mark packages with sideEffects: false, and prefer tree-shakeable libraries like lodash-es.

Detailed answer (senior level)

Tree shaking depends on static analyzable ES6 syntax. Named exports and direct imports maximize reduction. Default exports and side effects prevent shaking. In practice, combine with dynamic imports for heavy features. Always validate with a bundle analyzer — assumptions about what gets removed are often wrong.

  • Using default exports or import * as lib
  • Including side effects in modules (console.log, CSS imports)
  • Using non-tree-shakeable libraries (moment, full lodash)
  • Barrel files that re-export everything
  • Not checking bundle analyzer output
Key Takeaways
  • ✓Tree shaking requires ES6 modules and named imports
  • ✓Mark side-effect-free packages with "sideEffects": false
  • ✓Prefer lodash-es, date-fns, and modular libraries
  • ✓Use bundle analyzer to verify results regularly
  • ✓Tree shaking is most effective when combined with code splitting
  • ✓Write code with bundle size in mind from the start
Previous TopicCode Splitting: Optimize Bundle Size with Dynamic ImportsNext Topic Lazy Loading: Load Resources On-Demand

On this page