Import Attributes in JavaScript
Import attributes (formerly called “import assertions”) are a standard feature (ES2025) that let you pass metadata when importing modules. The proposal was renamed from assert to with and reached Stage 4. It is supported in Chrome 123+, Edge 123+, Safari 17.2+, and Node.js 22+.
Syntax — with keyword (standard)
The standard syntax uses the with keyword:
// Standard import attribute for JSON
import data from "./data.json" with { type: "json" };
// Dynamic import with attribute
const config = await import("./config.json", {
with: { type: "json" },
});Expanded Import Assertions
The expanded import assertions proposal extends this functionality to support more attributes and use cases:
// Proposed syntax (with expanded attributes)
import data from './data.json' with { type: 'json', lazy: true };
// Dynamic import with expanded attributes
const module = await import('./module.js', {
with: {
type: 'module',
integrity: 'sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC'
}
});Key Differences
The transition from assert to with reflects a change in semantics:
- Assertions vs. Attributes:
assertimplies checking a fact, whilewithindicates configuration - Expanded Capabilities:
withsupports more attributes beyond just type checking - Flexibility:
withallows for future extensions to the module loading system
Use Cases for Expanded Import Assertions
1. Module Type Specification
// Specify module type
import data from "./data.json" with { type: "json" };
import styles from "./styles.css" with { type: "css" };
import wasm from "./module.wasm" with { type: "webassembly" };2. Resource Integrity
// Verify resource integrity with hash
import library from "https://cdn.example.com/lib.js" with {
integrity: "sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC",
};3. Loading Strategies
// Lazy loading
import heavyModule from './heavy-module.js' with { lazy: true };
// Preload but don't execute
import criticalModule from './critical.js' with { preload: true, execute: false };4. Module Transformations
// Apply transformations during import
import legacyModule from "./legacy.js" with { transform: "legacy-compat" };
// Import with specific version requirements
import library from "external-lib" with { version: "^2.0.0" };Current Status and Support
Expanded import assertions are still in the proposal stage (Stage 3 in the TC39 process as of the latest update). Support varies across environments:
- Browsers: Limited support for basic import assertions
- Node.js: Experimental support for import assertions
- Bundlers: Varying levels of support through plugins
- Transpilers: Babel and similar tools can transform syntax
Practical Applications
Working with Different Data Formats
// Import different data formats with appropriate handling
import jsonData from "./data.json" with { type: "json" };
import yamlData from "./config.yaml" with { type: "yaml" };
import csvData from "./data.csv" with { type: "csv", delimiter: "," };
// Use the imported data
console.log(jsonData.title);
console.log(yamlData.settings.theme);
console.log(csvData[0].name);Enhanced Security for Third-Party Modules
// Import third-party module with integrity check
import analytics from 'https://cdn.analytics.com/script.js' with {
integrity: 'sha384-oqVuAfXRKap7fdgcCY5uykM6+R9GqQ8K/uxy9rx7HNQlGYl1kPzQho1wx4JwY8wC',
crossOrigin: 'anonymous'
};
// Import with permissions specification
import locationService from './location-service.js' with {
permissions: ['geolocation']
};Conditional Module Loading
// Import different modules based on environment
async function loadAppropriateModule() {
const isLegacyBrowser = checkIfLegacyBrowser();
if (isLegacyBrowser) {
return import("./legacy-module.js", {
with: { compat: true, polyfills: true },
});
} else {
return import("./modern-module.js", {
with: { optimized: true },
});
}
}Comparison with Other Module Features
| Feature | Purpose | Syntax |
|---|---|---|
| Import Assertions | Specify module type | import x from 'y' assert { type: 'json' } |
| Expanded Import Assertions | Configure module loading | import x from 'y' with { type: 'json', lazy: true } |
| Dynamic Import | Load modules on demand | import('./module.js') |
| Module Namespace | Import all exports | import * as module from './module.js' |
| Named Imports | Import specific exports | import { func, Class } from './module.js' |
Current Workarounds
Until expanded import assertions are widely supported, there are several alternatives:
1. Loaders and Bundler Plugins
// Webpack configuration
module.exports = {
module: {
rules: [
{
test: /\.yaml$/,
use: "yaml-loader",
},
{
test: /\.csv$/,
use: "csv-loader",
},
],
},
};2. Dynamic Loading with Custom Handling
// Manual handling of different file types
async function loadDataFile(path) {
const response = await fetch(path);
const fileExtension = path.split(".").pop().toLowerCase();
switch (fileExtension) {
case "json":
return response.json();
case "yaml":
case "yml":
const yamlText = await response.text();
return parseYaml(yamlText);
case "csv":
const csvText = await response.text();
return parseCSV(csvText);
default:
return response.text();
}
}
// Usage
const data = await loadDataFile("./config.yaml");3. Module Wrappers
// Wrap non-JavaScript resources in JS modules
// data-wrapper.js
import rawData from "./data.csv";
import { parseCSV } from "./csv-parser";
export default parseCSV(rawData);
// Usage
import data from "./data-wrapper.js";Best Practices
- Feature Detection: Check for support before using expanded import assertions
- Fallbacks: Provide alternative loading mechanisms for unsupported environments
- Documentation: Clearly document import attributes used in your codebase
- Security: Use integrity checks for third-party resources
- Minimal Attributes: Only use attributes that are necessary for your use case
// Feature detection for import assertions
function supportsImportAssertions() {
try {
new Function(
'return import("data:text/javascript,export default 0", { assert: { type: "js" } })',
);
return true;
} catch {
return false;
}
}
// Conditional loading based on support
async function loadData() {
if (supportsImportAssertions()) {
return import("./data.json", { assert: { type: "json" } });
} else {
const response = await fetch("./data.json");
return response.json();
}
}Future Directions
The expanded import assertions proposal opens the door for more advanced module loading features:
- Conditional Imports: Load different modules based on runtime conditions
- Progressive Loading: Load critical parts first, then non-critical parts
- Permissions Integration: Specify required permissions for modules
- Versioning: Import specific versions of modules
- Transformation Pipelines: Apply multiple transformations to imported modules
Interview Tips
- Explain the difference between import assertions (
assert) and expanded import assertions (with) - Describe practical use cases for different import attributes
- Discuss how expanded import assertions enhance security for third-party modules
- Explain current workarounds for environments that don’t support import assertions
- Demonstrate knowledge of the TC39 proposal process and the current status
- Discuss how expanded import assertions relate to other module system features
Test Your Knowledge
Take a quick quiz to test your understanding of this topic.