Web Fundamentals

JavaScript Module Systems: CJS vs ESM vs UMD

Web Fundamentals Map

Rendering & Browser Architecture

Critical Rendering PathScript Loading Patterns (async/defer)Event Loop Deep DiveJavaScript Module Systems (CJS, ESM, UMD)Dynamic Module Loading (import())Import on InteractionImport on VisibilityBrowser Rendering Pipeline & Layout ThrashingRendering Strategies (CSR, SSR, SSG, ISR)Streaming SSR & Progressive HTMLIslands ArchitectureReact Server ComponentsFramework Reactivity (React, Vue, Svelte, Solid)HTTP/1.1 vs HTTP/2 vs HTTP/3 (QUIC)DNS Resolution & TTL Caching

Performance

Core Web Vitals: LCP, INP, CLSPerformance Optimization Trade-offsCritical Resource PrioritizationCode Splitting & Dynamic ImportsTree Shaking & Dead Code EliminationLazy LoadingResource Hints: Preload, Prefetch & PreconnectText Compression: Gzip & BrotliImage & Video OptimizationAdaptive LoadingList VirtualizationWeb Workers vs Main ThreadMemory Leaks: Detection & PreventionManaging Third-Party ScriptsHow CDNs WorkHTTP Caching Deep DiveService Workers & Offline StrategyPWA Fundamentals

Security

Cross-Site Scripting (XSS)Cross-Site Request Forgery (CSRF)CORS ExplainedCORS Preflight, Credentials & MisconfigurationsContent Security Policy (CSP)Why is HTTPS Secure? (TLS/SSL)Authorization Best PracticesCookie Security & Session Hardening

State & Data Architecture

State Management Guide (Context vs Zustand vs Redux)React Query & Server State CachingData Fetching PatternsCaching StrategiesPagination: Offset vs Cursor-BasedReal-time Communication (WebSocket, SSE, Polling)
mediumWeb Fundamentals

JavaScript Module Systems: CJS vs ESM vs UMD

Learn the interview-ready mental model, practical trade-offs, and production patterns for this web fundamentals topic.

Topic content

TL;DRESM (static, tree-shakable) is the modern standard • CJS (runtime, dynamic) is legacy Node • UMD is for broad legacy compatibility
Very High Signal
Google
Meta
Agoda
Meesho
30-Second Answerstart every interview with this

JavaScript has evolved through multiple module systems. CommonJS (CJS) uses synchronous require() and is runtime-based. ES Modules (ESM) use static import/export syntax, enabling tree-shaking and better optimization. UMD is a legacy wrapper that works across environments. Understanding static vs runtime resolution is the key differentiator for performance and tooling.

CJS containers are opened and inspected only when the ship arrives at runtime (dynamic). ESM containers are scanned and optimized at the port (build time) with clear labels, allowing removal of unused cargo (tree-shaking). UMD is an old multi-format shipping crate that works everywhere but is bulky.

Author Code
Resolve Dependencies
Bundler (Tree-shaking + Optimization)
Runtime Execution (CJS vs ESM semantics)

1CommonJS (CJS)

Legacy Node.js module system. Uses synchronous require(). Modules are loaded and executed at runtime. Dynamic imports are possible but prevents many build-time optimizations.

math.cjsjs
const add = (a, b) => a + b;
module.exports = { add };

2ES Modules (ESM)

Modern standard. Uses static import/export. Enables tree-shaking, scope hoisting, and top-level await. Native support in modern browsers and Node (with type: module).

math.mjsjs
export const add = (a, b) => a + b;

export default { add };

3UMD (Universal Module Definition)

Legacy pattern designed to work in browser, Node, and AMD environments. Usually generated by bundlers for library distribution. Larger output size and rarely used in modern apps.

umd-example.jsjs
(function(root, factory) {
  if (typeof define === 'function' && define.amd) {
    define([], factory);
  } else if (typeof module === 'object' && module.exports) {
    module.exports = factory();
  } else {
    root.myLib = factory();
  }
}(typeof self !== 'undefined' ? self : this, function() {
  return { /* lib */ };
}));

4Bundler Role & Interop

Bundlers (Webpack, Vite, Rollup) resolve the module graph at build time. ESM enables powerful optimizations. Interop between CJS and ESM can be tricky — default exports from CJS become .default in ESM.

Key Takeaways
  • ✓ESM is the modern standard — use it by default
  • ✓CJS is runtime-based and blocks tree-shaking
  • ✓Static analysis in ESM enables powerful bundler optimizations
  • ✓CJS ↔ ESM interop requires care (especially default exports)
  • ✓UMD is mostly legacy for CDN library distribution
PreviousNext

Topic Guide

On this page