Importing JSON Files in Node.js: ERR_IMPORT_ASSERTION_TYPE_MISSING Error
Problem Statement
When importing JSON files in Node.js ES modules, you may encounter the error:
TypeError [ERR_IMPORT_ASSERTION_TYPE_MISSING]:
Module "file:///path/to/your/file.json"
needs an import assertion of type "json"
This error typically occurs in Node.js version 17 and later when trying to import JSON files without the proper import assertion syntax:
// This will cause the error in newer Node.js versions
import countryTable from './data/countries.json';
The error arises because Node.js now requires explicit type assertions for JSON imports as a security measure to ensure the imported content matches the expected format.
Solutions
1. Modern Import Assertion Syntax (Recommended)
For Node.js v17.1.0 and later, use the with
keyword for import assertions:
import countryTable from "./data/countries.json" with { type: "json" };
This is the current standard syntax that follows the latest ECMAScript proposal.
2. Legacy Assertion Syntax
For compatibility with older versions that support import assertions but before the with
keyword was standardized:
import countryTable from "./data/countries.json" assert { type: "json" };
WARNING
The assert
syntax is considered legacy and may be deprecated in future Node.js versions. Prefer the with
syntax for new code.
3. Using createRequire for Compatibility
For environments where import assertions aren't supported or when working with older Node.js versions (v12+):
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);
const countryTable = require('./data/countries.json');
This approach creates a CommonJS-style require function that works within ES modules.
4. File System Reading Approach
If you prefer to avoid both import assertions and createRequire
, you can read the JSON file directly:
import { readFile } from 'fs/promises';
const loadJSON = async (path) => {
const data = await readFile(new URL(path, import.meta.url));
return JSON.parse(data);
};
// Usage
const countryTable = await loadJSON('./data/countries.json');
Or synchronously:
import { readFileSync } from 'fs';
const loadJSON = (path) => {
return JSON.parse(readFileSync(new URL(path, import.meta.url), 'utf8'));
};
// Usage
const countryTable = loadJSON('./data/countries.json');
Version Compatibility Guide
Node.js Version Support
- Node.js ≥ 17.1.0: Use
import with { type: "json" }
syntax - Node.js 12-17: Use
createRequire()
or filesystem methods - Node.js < 12: Use CommonJS
require()
(not in ES modules)
Migration Example
If you're upgrading from an older codebase, here's how to migrate your JSON imports:
Before:
import countryTable from './data/countries.json';
After:
import countryTable from './data/countries.json' with { type: "json" };
Common Issues and Solutions
ESLint Compatibility
If your ESLint version doesn't support the new import assertion syntax, you might need to:
- Update ESLint and relevant plugins
- Use the filesystem reading approach as a temporary workaround
- Configure ESLint to ignore the new syntax until support is added
Mixed Module Systems
When working with both ES modules and CommonJS, the createRequire
approach provides the most consistent behavior across different Node.js versions.
Best Practices
- Always specify the type assertion for JSON imports in modern Node.js
- Check your Node.js version and use the appropriate syntax
- Consider using the filesystem approach for maximum compatibility if you're creating libraries
- Keep dependencies updated to ensure ESLint and other tools support the latest syntax
By following these approaches, you can successfully import JSON files in Node.js ES modules without encountering the ERR_IMPORT_ASSERTION_TYPE_MISSING
error, regardless of your Node.js version or project constraints.