in modern web development fundamentally changes how browsers fetch, parse, and execute JavaScript files compared to classic scripts. Setting the script type to a module automatically activates deferred execution, enforces str"> in modern web development fundamentally changes how browsers fetch, parse, and execute JavaScript files compared to classic scripts. Setting the script type to a module automatically activates deferred execution, enforces str" />

JavaScript Script Type Module Loading and Execution

Using <script type="module"> in modern web development fundamentally changes how browsers fetch, parse, and execute JavaScript files compared to classic scripts. Setting the script type to a module automatically activates deferred execution, enforces strict mode, encapsulates code within local module scopes, handles dependency graphs asynchronously, and requires cross-origin security checks.

Automatic Deferred Execution

Classic <script> tags block HTML parsing by default unless configured with defer or async attributes. In contrast, <script type="module"> is automatically deferred.

The browser downloads the module script and all of its imported dependencies in parallel with HTML parsing. The script’s execution is delayed until the HTML document has finished parsing, running just before the DOMContentLoaded event fires.

Native Module Scoping and Strict Mode

Classic scripts execute in the global scope, meaning top-level variables and functions attach directly to the window object.

Module scripts introduce their own lexical scope: * Module-Level Scope: Top-level variables, functions, and classes are private to the module file unless explicitly shared using export. * Automatic Strict Mode: All code within a module script runs in "use strict" mode by default, eliminating the need to declare it manually. * this Binding: The top-level this value evaluates to undefined instead of referencing the window object.

Asynchronous Dependency Resolution

When a module uses import statements, the browser treats the code as a dependency graph:

  1. Parsing: The browser scans the entry script for import statements.
  2. Fetching: All imported modules and their sub-dependencies are fetched over the network concurrently.
  3. Execution Order: The browser waits until the entire dependency tree is fully downloaded and parsed before executing the files. Execution proceeds depth-first, ensuring dependencies run before the files that import them.

Single Execution (Singleton Evaluation)

If a module script or an imported module file is included multiple times across a webpage, the browser downloads and executes it only once. Subsequent imports reuse the same cached module instance, preventing duplicate execution and state conflicts.

CORS Requirements

Module scripts are subject to Cross-Origin Resource Sharing (CORS) policies. Unlike classic scripts, external module scripts fetched from different domains must include valid Access-Control-Allow-Origin headers. Additionally, module scripts cannot be loaded directly from the local filesystem (file://) due to CORS restrictions, requiring a local or remote web server.

The async Attribute on Modules

While module scripts default to deferred behavior, the async attribute can be explicitly added via <script type="module" async>. When async is applied: * The module and its imported dependencies load in the background. * The script executes immediately once all dependencies are loaded, regardless of whether HTML parsing is complete.