Import Attributes and Type JSON in Modern JavaScript
This article explains the purpose and functionality of import
attributes in modern JavaScript, focusing on type: "json".
Import attributes allow developers to attach explicit metadata to module
import declarations, enabling JavaScript runtimes to safely and natively
import non-JavaScript resources—such as JSON documents—without relying
on bundler-specific transforms or asynchronous fetch
workarounds.
Preventing Security Vulnerabilities
The primary reason for introducing the type: "json"
attribute is security, specifically mitigating MIME-type confusion and
code execution attacks.
In standard JavaScript module loading, the runtime executes imported
resources as executable JavaScript code. If a web application attempts
to import a JSON file from a remote server without explicit type
verification, a malicious or compromised server could return a file
containing executable JavaScript with a text/javascript
MIME type instead of JSON data.
By adding with { type: "json" }, the developer
explicitly declares the expected format. If the imported resource cannot
be parsed as valid JSON or if the server delivers it with an
incompatible MIME type, the module graph instantiation fails
immediately, preventing arbitrary script execution.
Native and Ergonomic Resource Loading
Historically, importing JSON required developers to use
fetch() at runtime or depend on build tools like Webpack or
Rollup to transform JSON files into JavaScript objects. Import
attributes standardize this behavior across all environments.
Static import syntax:
import config from "./config.json" with { type: "json" };Dynamic import syntax:
const data = await import("./data.json", {
with: { type: "json" }
});Using these native constructs, JSON files become full participants in
the ECMAScript Module (ESM) graph, allowing synchronous-like access at
module initialization without manual parsing steps like
JSON.parse().
Static Analysis and Dependency Graphs
Import attributes integrate directly into the static structure of
ECMAScript modules. Because with { type: "json" } is
statically analyzable, JavaScript runtimes and build tools can build
accurate dependency trees before executing any code. This determinism
allows engines to optimize resource preloading, tree-shaking, and
bundling pipelines consistently across both browsers and server-side
runtimes like Node.js and Deno.
Extensibility for Future Formats
While type: "json" is the most common use case, import
attributes provide an extensible framework for other non-JavaScript
resources. The same architecture supports additional module types, such
as CSS style sheets (type: "css") and WebAssembly modules,
creating a unified standard for all web resource imports.