The <script> Element
Technical Summary
The script element can represent a classic script, a module script, or a non-executed data block, depending on its attributes and type.
For external classic scripts, async evaluates as soon as the script is ready, while defer evaluates after parsing. Module scripts are evaluated after parsing by default; defer has no effect on them.
Definition / Variants
| Variant | Selection point | Processing summary |
|---|---|---|
| Classic script | No type, or a JavaScript MIME type | Evaluated as ordinary JavaScript. Without timing attributes, it blocks parsing while it is fetched and evaluated |
| Module script | type="module" | Fetches module dependencies and evaluates after parsing by default |
| Data block | A non-JavaScript type | Not evaluated as a script; an application can read its contents as data |
The type attribute is therefore a processing condition, not merely a label for presentation.
Processing order
| Condition | Fetching | Evaluation |
|---|---|---|
| classic / external / no timing attribute | Fetched while parsing | Immediately after fetching; parsing is paused |
classic / external / async | In parallel with parsing | When ready; order is not guaranteed |
classic / external / defer | In parallel with parsing | After parsing, in document order |
| module | Fetched with its module dependencies | After parsing by default; async can select earlier evaluation |
classic + no async/defer → fetch → evaluate → continue parsing
classic + async → fetch in parallel → evaluate when ready
classic + defer → fetch in parallel → evaluate after parsing
module → fetch dependencies → evaluate after parsing
Attributes and boundaries
- srcSpecifies the external script source URL. An element using an external source should not also contain executable source text.
- typeSelects a classic script, module script, data block, or another defined processing mode.
- async / deferSelects fetching and evaluation timing for relevant external scripts.
deferhas no effect on module scripts. - policyCSP is a separate policy boundary and can prevent an otherwise valid script from executing.
Fetch and failure boundary
Processing does not end when the element's kind is selected. Fetching the source, fetching module dependencies, CORS, and CSP can all affect whether evaluation proceeds. In particular, cross-origin module scripts require the CORS protocol.
source markup
↓ determine script kind
↓ apply policy gates
↓ fetch source / module dependencies
↓ evaluate or expose data block
Fact / Evidence
Key facts are mapped to their conditions, review status, and evidence locations. Unresolved scope remains visible in the Coverage section below.
| Type | Fact | Condition / Scope | Status | Evidence |
|---|---|---|---|---|
| SPEC | The type attribute selects a classic script, module script, or data block. | The value is absent, a JavaScript MIME type, module, or another non-script type. | Reviewed | HTML Standard: the script element |
| SPEC | An external classic script without async or defer pauses parsing while it is fetched and evaluated. | External classic script; neither timing attribute is present. | Reviewed | HTML Standard: the script element |
| SPEC | async evaluates when ready, while defer waits for parsing and preserves document order. | External classic scripts; async does not guarantee order. | Reviewed | HTML Standard: scripting guidance |
| SPEC | Module scripts are evaluated after parsing by default; defer has no effect on them. | type="module"; async can select earlier evaluation. | Reviewed | HTML Standard: the script element |
| SPEC | External scripts and module dependencies are subject to resource-fetching and policy conditions. | External or cross-origin resources; Fetch and policy gates can affect evaluation. | Reviewed | Fetch Standard |
Evidence
- HTML Standard: The script element — element kinds, attributes, and processing model
- HTML Standard: Scripting, Edition for Web Developers — async, defer, and module evaluation timing
- Fetch Standard — external resource fetching and CORS boundaries
Implementation Evidence
Implementation observations are recorded separately from normative claims. Unrun items are not treated as reviewed.
Shared fixture / environment: One HTML document with a classic script, an application/json data block, an inline module, and a dynamically inserted classic script. Chrome 152.0.0.0 / Windows NT 10.0 / checked 2026-09-13.
| Type | Reproducible scope | Record required | Status |
|---|---|---|---|
| IMPL | Classic, module, and data-block kinds; dynamic-insertion timing | Chrome 152.0.0.0 / Windows NT 10.0 / 2026-09-13. The classic script ran at loading; the dynamically appended classic script ran immediately during parsing; the module ran at interactive. The application/json block remained a data block and produced no execution log. | Reviewed |
| WPT | Tests related to script kinds, execution order, module dependencies, and Fetch/CORS | Mapped to 106-noimport.html, 106-module-noimport.html, dynamically-created-defer-script.html, and data-url.html. On 2026-09-15 in Chrome 152.0.0.0 / Windows NT 10.0, all four selected files passed 4/4 on wpt.live. Unselected WPT coverage and other browsers remain open. | Partial (4/4 pass) |
| AAM | Effect of executable scripts and data blocks on the accessibility tree | Chrome 152.0.0.0 / Windows NT 10.0 / 2026-09-13. The classic script, module, and data block themselves were not exposed in the AX tree; visible headings, form controls, and table content were exposed. | Observed |
Use the WPT repository for test mapping and HTML-AAM for accessibility criteria.
Coverage / Open Issues
- ReviewedClassic, module, and data-block distinctions; the basic timing model for async and defer
- OpenComplete processing branches, parser insertion, and dynamic insertion paths
- OpenCross-Spec details for CSP, Fetch, CORS, Referrer Policy, and Integrity
- OpenThis implementation and AX observation covers one Chrome environment only. External async/defer scripts, multi-browser comparison, WPT, historical changes, and operational differences remain unregistered.
This is initial coverage. It does not claim that every fact about the script element has been verified or that every implementation produces the same result.
Related surface
For minimal examples and guidance on choosing defer, async, or modules, see the script element page in Yugien.