DevPrep
  • Interview Prep
  • Projects
  • Resources
  • Pricing
  • About Us
Submit Question
DevPrep
  • Pricing
  • About Us
Submit Question
  1. Home
  2. Articles
  3. Frontend Engineering
  4. Understanding JavaScript Modules: CommonJS vs ESM Deep Dive
XLinkedInReddit
MediumFrontend Engineering

Understanding JavaScript Modules: CommonJS vs ESM Deep Dive

D
DevPrep Team
February 10, 2026·1 min read·0
Table of Contents
  • CommonJS (CJS)
  • ES Modules (ESM)
  • Key Differences
  • The Live Binding Gotcha
  • Interop Challenges

The module system you choose affects bundling, tree-shaking, and runtime behavior. Here's what I've learned shipping both at Google.

CommonJS (CJS)

// Synchronous, dynamic
const fs = require("fs");
module.exports = { readFile: fs.readFile };

// Can be conditional
if (process.env.NODE_ENV === "test") {
  module.exports = require("./mock");
}

CJS loads modules synchronously. require() is a function call — it can appear anywhere, even inside conditions. This makes static analysis impossible.

ES Modules (ESM)

// Static, async
import { readFile } from "fs/promises";
export { readFile };

// CANNOT be conditional
// if (x) import y from "z"; // SyntaxError!

ESM imports are static declarations. The engine can analyze the entire dependency graph before execution — this enables tree-shaking.

Key Differences

FeatureCJSESM
LoadingSynchronousAsynchronous
BindingValue copyLive binding
thismodule.exportsundefined
Tree-shakingNot possibleSupported
Top-level awaitNoYes

The Live Binding Gotcha

// counter.mjs
export let count = 0;
export function increment() { count++; }

// main.mjs
import { count, increment } from "./counter.mjs";
console.log(count); // 0
increment();
console.log(count); // 1 — live binding!

// In CJS, count would still be 0 (value copy)

Interop Challenges

  • CJS require() of ESM: Not supported (use dynamic import() instead)
  • ESM import of CJS: Works but you get the whole module.exports as default
  • __dirname doesn't exist in ESM — use import.meta.url

Related Articles

MediumFrontend Engineering

System Design #12: Design a Multi-Step Form Wizard

7 min read
MediumFrontend Engineering

Mastering Senior-Level JavaScript Interview Concepts

2 min read
MediumFrontend Engineering

System Design #9: Design a Collaborative Text Editor

9 min read

Comments (0)

Sign in to leave a comment.

No comments yet. Be the first to comment.

Table of Contents

  • CommonJS (CJS)
  • ES Modules (ESM)
  • Key Differences
  • The Live Binding Gotcha
  • Interop Challenges

Series

View all Frontend Engineering articles →

Practice

  • JavaScript
  • DSA
  • Machine Coding
  • System Design

Resources

  • Learning Tracks
  • Articles
  • Roadmaps
  • Compare Concepts
  • Glossary
  • Developer Tools
  • All Questions

Company

  • About
  • Pricing

Legal

  • Privacy Policy
  • Terms of Service
DevPrep

© 2026 DevPrep. All rights reserved.