ReviseAlgo Logo

Modules & Bundling

ES Modules — import & export

Master modern ECMAScript Modules (ESM) in JavaScript. Learn static imports, exports syntax, browser module integration, and runtime compilation rules.

Last Updated: July 15, 2026 10 min read

1. Introduction

ES Modules (ESM) is the official, standardized module system for JavaScript. It manages modules using the import and export keywords, enabling static analysis and native module loading directly in web browsers.

2. Why It Matters

ES Modules are parsed statically before code execution. This design allows bundlers to perform optimizations like Tree Shaking (removing unused code) and allows browsers to load modules in parallel, improving performance.

3. Real-World Analogy

Think of a Customs Declaration System:

  • CommonJS (Packed trunk): You bring a sealed shipping crate into a country. Customs must open and scan the entire crate (run the module code) to find what is inside before they can approve it.
  • ES Modules (Declared cargo manifesto): You attach a clear cargo manifest list showing exactly what is exported and imported (static declarations) to the outside of the container. Customs reads the manifest and routes the container immediately, without needing to open it first (enabling static analysis and optimization).

4. ES Modules Syntax

Unlike CommonJS, ES Modules use explicit export statements to share functions, classes, or values:

5. ES Modules in the Browser

To run ES Modules natively in web browsers, load script tags using the type="module" attribute:

Characteristics of script modules in browsers:
Strict Mode: Script modules automatically run in strict mode (no need to specify "use strict").
CORS Requirements: Modules are loaded using CORS, requiring server responses to include correct headers.
Deferred Load: Script modules are deferred by default, loading in parallel and executing only after the DOM has finished parsing.

6. Practical Example

This script demonstrates importing all exports from a module into a namespace object:

7. Common Mistakes

  • Omitting file extensions in relative imports: Modern bundlers (like Webpack) resolve files without extensions automatically, but native browser modules and Node.js ESM require relative imports to specify file extensions explicitly: import { add } from './math.js'.

8. Quick Quiz

Q1: Which attribute is required on script tags to run ES Modules natively in the browser?

A) type="javascript"

B) type="module"

Answer: B — The type="module" attribute tells the browser to parse the script tag as an ES Module.

9. Scenario-Based Challenge

The Multi-Library Scope Conflict Resolver:

An application imports two separate math modules: math-lib.js and physics-math.js. Both modules export a function named calculate(). Write the import statement that renames (aliases) these functions during import to resolve the name conflict.

10. Debugging Exercise

Explain why this native browser script tag fails to execute during page load:

<!-- HTML -->
<script type="module">
  // Objective: import calculation helpers
  import { add } from './math'; // throws error! Why?
</script>
View Solution

Diagnosis: Native browser ES Modules do not support automatic file resolution. Relative import paths must specify file extensions explicitly.

Fix: Add the .js file extension to the import path:

import { add } from './math.js'; // Specifies extension

11. Interview Questions

🟢 Q1: Compare ES Modules (ESM) and CommonJS (CJS) in terms of loading timing and optimizations.

Answer:
CommonJS: Loads modules synchronously. The module code runs during the require call, exporting a copied reference. Because exports are determined dynamically at runtime, bundlers cannot optimize code structure easily.
ES Modules: parsed statically before code execution. Imports and exports are resolved before the code runs, creating live bindings to the exported values. This design allows bundlers to analyze dependency chains statically and perform optimizations like tree shaking.

12. Production Considerations

  • CORS Headers: When serving ES Modules natively in production, configure the hosting server to include correct CORS headers (like Access-Control-Allow-Origin). Browsers fetch modules using CORS, and missing headers will cause module loads to fail.