Skip to content

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:

javascript
// 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

For Node.js v17.1.0 and later, use the with keyword for import assertions:

javascript
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:

javascript
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+):

javascript
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:

javascript
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:

javascript
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:

javascript
import countryTable from './data/countries.json';

After:

javascript
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:

  1. Update ESLint and relevant plugins
  2. Use the filesystem reading approach as a temporary workaround
  3. 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

  1. Always specify the type assertion for JSON imports in modern Node.js
  2. Check your Node.js version and use the appropriate syntax
  3. Consider using the filesystem approach for maximum compatibility if you're creating libraries
  4. 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.