Import Attributes (ES2025) enable native imports of JSON, CSS, and other non-JavaScript resources using the with keyword. No bundler plugins required.
Import attributes provide metadata to the module loader about how to interpret an imported file. They use the with keyword after the module specifier:
// Basic syntax
import data from './file.json' with { type: 'json' };
// The attribute tells the runtime:
// "This file should be parsed as JSON, not JavaScript"
// Without the attribute, importing a .json file
// would either fail or be treated as JavaScript
Import attributes were standardized in ECMAScript 2025 and are supported across all major environments:
Browsers
Chrome 123+, Firefox 128+, Safari 17.2+
Node.js
v22+ (stable, no flag needed)
Deno & Bun
Full support in current versions
Import JSON files directly as ES Modules. The JSON is parsed and available as the default export:
// Import entire JSON file
import config from './config.json' with { type: 'json' };
console.log(config.apiUrl); // "https://api.example.com"
console.log(config.debug); // false
// Import in a dynamic import
const pkg = await import('./package.json', {
with: { type: 'json' }
});
console.log(pkg.default.version); // "1.0.0"
// Re-export from JSON
export { default as config } from './config.json' with { type: 'json' };
Security Note:
The type attribute prevents JSON files from being executed as JavaScript. Without it, a malicious .json file could contain executable code. The attribute ensures the content is only parsed as JSON data.
Import CSS files as Constructable Stylesheets, ideal for Web Components and Shadow DOM:
// Import a CSS file as a CSSStyleSheet
import styles from './component.css' with { type: 'css' };
// Apply to the document
document.adoptedStyleSheets = [styles];
// Apply to a Shadow DOM (Web Components)
class MyComponent extends HTMLElement {
constructor() {
super();
const shadow = this.attachShadow({ mode: 'open' });
shadow.adoptedStyleSheets = [styles];
shadow.innerHTML = '<p>Styled content</p>';
}
}
customElements.define('my-component', MyComponent);
Browser Support:
CSS module scripts are supported in Chrome 93+ and Edge 93+. Firefox and Safari support is still in development. For cross-browser projects, continue using bundler CSS handling or check support before using.
Use import attributes with dynamic import() by passing an options object as the second argument:
// Dynamic import with attributes
const config = await import('./config.json', {
with: { type: 'json' }
});
console.log(config.default);
// Conditional loading based on environment
async function loadTheme(themeName) {
const theme = await import(
`./themes/${themeName}.css`,
{ with: { type: 'css' } }
);
document.adoptedStyleSheets = [theme.default];
}
// Load JSON data on demand
async function loadLanguage(lang) {
const translations = await import(
`./i18n/${lang}.json`,
{ with: { type: 'json' } }
);
return translations.default;
}
If your code uses the older assert syntax (import assertions), update to with:
// OLD - import assertions (DEPRECATED)
import data from './data.json' assert { type: 'json' };
// NEW - import attributes (ES2025 STANDARD)
import data from './data.json' with { type: 'json' };
// OLD - dynamic import with assert
const mod = await import('./data.json', {
assert: { type: 'json' }
});
// NEW - dynamic import with with
const mod = await import('./data.json', {
with: { type: 'json' }
});
Why the Change?
The assert keyword was renamed to with because attributes can influence how a module is loaded (not just validate it after loading). This is a breaking change from the earlier Stage 3 proposal - make sure to update your code.
The import attributes mechanism is designed to be extensible. Future types under discussion include:
HTML Modules
Import HTML templates as modules - currently a WICG proposal
WebAssembly
Source phase imports may use attributes for WASM compilation options
YAML / TOML
Community proposals for structured data formats beyond JSON
Custom Types
Runtimes may support custom attribute types for environment-specific needs
Import Attributes (ES2025) allow you to pass metadata to the module loader using the 'with' keyword. They tell the runtime how to interpret the imported file, enabling native imports of JSON, CSS, and potentially other file types without bundler plugins.
Import attributes replace import assertions. The syntax changed from 'assert { type: "json" }' to 'with { type: "json" }'. The key difference is that attributes can influence how a module is loaded (not just validated), which is more powerful and future-proof.
Yes! Since ES2025, you can import JSON files natively using: import data from './data.json' with { type: 'json' }. This works in Node.js 22+, Chrome, Firefox, Safari, and Edge without any bundler configuration.
All modern browsers support import attributes with the 'with' keyword: Chrome 123+, Edge 123+, Firefox 128+, Safari 17.2+. Node.js 22+ and Deno 1.37+ also support them. The older 'assert' syntax should no longer be used.