ES Modules Logo ESModules.com

ES Modules Glossary & Terminology

A comprehensive reference of ES Module terminology. From bare specifiers to tree-shaking, find clear definitions for every module concept you will encounter.

AMD

Asynchronous Module Definition. A pre-ESM module format designed for browsers, used with RequireJS. Modules declare dependencies as an array and receive them as callback arguments. Largely obsolete, replaced by ES Modules.

Bare Specifier

A module import path that does not start with ./, ../, or /. Examples: 'lodash', 'react'. Browsers cannot resolve these natively - they require import maps or a bundler.

Barrel File

An index.js file that re-exports from multiple other modules, providing a single entry point: export { foo } from './foo.js'. Convenient but can harm tree-shaking and increase bundle size if not handled carefully.

Bundler

A tool that combines multiple module files into one or more output files for deployment. Examples: Rollup, webpack, esbuild, Vite (uses Rollup), Rspack. Bundlers resolve imports, perform tree-shaking, and optimize output.

Circular Dependency

When module A imports from module B and module B imports from module A (directly or through a chain). ES Modules handle this via live bindings, but circular dependencies can cause variables to be undefined during initialization.

CommonJS

The module system used by Node.js since 2009. Uses require() for imports and module.exports for exports. Synchronous loading, value copies (not live bindings), dynamic structure. Being gradually replaced by ESM.

Conditional Export

A package.json "exports" field that maps different entry points based on conditions like "import", "require", "browser", or "default". Allows packages to serve different code to ESM and CJS consumers.

Dead Code Elimination

The process of removing code that is never executed or referenced from the final output. Tree-shaking is a specific form of dead code elimination that operates at the module export level. Enabled by ESM's static structure.

Default Export

A module's primary export, declared with export default. Each module can have at most one default export. Importers can choose any local name: import anything from './mod.js'.

Deferred Evaluation

A pattern or proposal (TC39 Stage 3: import defer) where a module's code is not executed until one of its exports is first accessed. Reduces startup cost for modules that may not be needed immediately.

Dynamic Import

Loading a module at runtime using import('./module.js'), which returns a Promise. Unlike static imports, dynamic imports can use computed paths and appear inside conditionals, loops, or functions. Used for code splitting and lazy loading.

Entry Point

The starting module that a bundler or runtime begins loading from. All other modules are discovered by following its import statements. In package.json, defined by "main", "module", or "exports" fields.

ES Module

The official JavaScript module system standardized in ECMAScript 2015. Uses import and export syntax, provides live bindings, enforces strict mode, supports static analysis, and works in browsers, Node.js, Deno, and Bun.

Export Map

The "exports" field in package.json that defines which module entry points a package exposes. Controls what consumers can import and enables conditional exports for different environments (ESM, CJS, browser, Node.js).

Import Attributes

A syntax for providing metadata about imports using the with keyword: import data from './data.json' with { type: 'json' }. Standardized in ES2025. Used for JSON modules, CSS modules, and future non-JavaScript module types.

Import Map

A JSON configuration in a <script type="importmap"> tag that tells the browser how to resolve bare specifiers. Maps package names to URLs, enabling bundler-free development. Supported in all modern browsers.

Import Specifier

The string that identifies the module to import. Three types: relative ('./utils.js'), absolute ('https://cdn.example.com/lib.js'), and bare ('lodash'). Each resolves differently depending on the environment.

JSON Module

A JSON file imported as an ES Module: import config from './config.json' with { type: 'json' }. The JSON data becomes the module's default export. Requires import attributes for security (prevents MIME type confusion attacks).

Live Binding

An ES Module feature where imported bindings are references to the exporting module's variables, not copies. If the exporting module changes a value, all importers see the update immediately. This is fundamentally different from CommonJS value copying.

Loader

The runtime mechanism that fetches, parses, and evaluates modules. Browsers use the HTML spec's module loader; Node.js has its own loader with hooks for customization (--loader flag). Loaders handle URL resolution, file fetching, and module caching.

Module Graph

The dependency tree formed by all import relationships starting from an entry point. The runtime builds this graph by analyzing static imports before executing any module code. The graph determines evaluation order and enables optimizations.

Module Record

The internal representation of a parsed module in the JavaScript engine. Contains the module's source text, import/export entries, requested modules, and evaluation status. Each module URL has exactly one Module Record (singleton).

Module Scope

Each ES Module has its own top-level scope - variables declared at the top level are not added to the global object. This eliminates global pollution. Only explicitly exported values are accessible to other modules.

Named Export

An export with a specific identifier: export function add() {} or export { add }. Must be imported by the exact name (with optional renaming via as). A module can have any number of named exports.

Namespace Import

Importing all exports of a module as a single object: import * as utils from './utils.js'. The namespace object has properties for each named export and a default property for the default export. Always a live, read-only object.

Package Exports

The "exports" field in package.json (Node.js 12.7+). Defines the public API of a package, restricts access to internal files, and supports subpath exports ("./utils") and conditional exports ("import"/"require").

Re-export

Exporting something that was imported from another module: export { foo } from './other.js'. The re-exporting module never has a local binding to the value. Used in barrel files and to create public API surfaces.

Resolution Algorithm

The process of converting a module specifier to an absolute URL or file path. Browsers resolve relative to the importing module's URL. Node.js checks package.json exports, then node_modules. Import maps customize browser resolution.

Side Effects

Code that executes at module evaluation time and affects state outside the module (DOM manipulation, global variable assignment, polyfills). The "sideEffects": false field in package.json tells bundlers it is safe to tree-shake unused modules entirely.

Source Phase Import

A TC39 proposal (import source mod from './module.wasm') that gives access to a module's source representation (like a WebAssembly.Module) without evaluating it. Enables compiling and instantiating WebAssembly modules with custom imports.

Static Analysis

Analyzing code without executing it. ES Module imports/exports are static (determinable at parse time), unlike CommonJS require() which can be dynamic. Static analysis enables tree-shaking, type checking, and IDE autocompletion.

Subpath Import

The "imports" field in package.json that creates private import aliases within a package: "#utils": "./src/utils.js". Only usable within the package itself. Useful for mapping platform-specific implementations.

Top-Level Await

Using await at the module's top level without wrapping it in an async function: const data = await fetch('/api'). Standardized in ES2022. The importing module waits for the awaited promise to resolve before executing.

Tree-Shaking

A bundler optimization that removes unused exports from the final output. Named after "shaking a tree" to remove dead leaves. Only possible with ES Modules because their static structure allows bundlers to determine what is used at build time.

UMD

Universal Module Definition. A wrapper pattern that makes a module work in AMD, CommonJS, and browser globals. Characterized by a boilerplate IIFE that detects the environment. Still used by some libraries for maximum backward compatibility.

Frequently Asked Questions