Skip to content

Node.js v22 JSON Import SyntaxError: Unexpected identifier 'assert'

Problem Statement

When migrating from Node.js 21 to Node.js 22, you may encounter the error SyntaxError: Unexpected identifier 'assert' when attempting to import JSON files using the syntax:

javascript
import config from "./some-config-file.json" assert { type: "json" };

This code worked correctly in Node.js 21 but fails in Node.js 22 due to deliberate syntax changes in the ECMAScript specifications. The error appears immediately during module resolution:

text
SyntaxError: Unexpected identifier 'assert'
    at compileSourceTextModule (node:internal/modules/esm/utils:337:16)
    at ModuleLoader.moduleStrategy (node:internal/modules/esm/translators:166:18)
    at callTranslator (node:internal/modules/esm/loader:436:14)
    at ModuleLoader.moduleProvider (node:internal/modules/esm/loader:442:30)
    at async ModuleJob._link (node:internal/modules/esm/module_job:106:19)

This issue occurs specifically because Node.js 22 removed support for "import assertions" in favor of the newer "import attributes" specification.

Why This Change Occurred

The syntax change results from the evolution of the ECMAScript proposal:

  1. The original assert syntax (import assertions) was supported in Node.js 17.1+ and 16.14+
  2. The proposal was renamed to "import attributes" with the with keyword replacing assert
  3. Node.js 22 implements the finalized specification, removing assert syntax entirely
  4. This change occurred because future import attributes will have functionalities beyond simple assertions

Note

Despite this syntax change, JSON import behavior remains identical - only the keyword has changed.

Solution 1: Use with Keyword (Node.js 18.20+)

Update your import statement to use the with keyword instead of assert:

javascript
import config from "./some-config-file.json" with { type: "json" };

Pros:

  • Minimal code change
  • Maintains static import advantages
  • Follows current ECMAScript standards

Cons:

  • Only supported in Node.js 18.20 and later
  • Breaks compatibility with Node v16 and v17

Use Node's built-in createRequire to load JSON files in a version-agnostic way:

javascript
import { createRequire } from 'node:module';
const require = createRequire(import.meta.url);

// Works in all Node versions since v12.2.0
const config = require('./some-config-file.json');

Advantages:

  • Full backward compatibility (works in Node.js v12.2+)
  • Maintains JSON module caching (identical to import behavior)
  • Simple implementation requiring minimal code changes

Solution 3: Manual JSON Parsing

If you need to avoid all module system features, manually read and parse the JSON file:

javascript
import fs from 'node:fs/promises';

const config = JSON.parse(
  await fs.readFile(
    new URL('./some-config-file.json', import.meta.url),
    'utf8'
  )
);

Use When:

  • Direct filesystem access is required
  • You need special JSON parsing behavior
  • Maintaining Node v12 compatibility (without createRequire)
  • Modifying JSON files during program execution

Performance Note

Manual parsing doesn't cache JSON contents. For frequently accessed files, implement caching or use createRequire.

Compatibility Table

SolutionNode v12.2+Node v16-17Node v18.20+Node v22+
assert (original)
with syntax
createRequire method
Manual parsing

Final Recommendation

For most projects, Solution 2 (createRequire) provides the best balance of:

  • Compatibility across Node versions
  • Performance with built-in caching
  • Code simplicity and maintainability

Migrating to with syntax (Solution 1) is appropriate if you exclusively support Node.js 18.20+. Reserve Solution 3 for edge cases requiring direct filesystem access or specialized JSON parsing.