resolveJsonModule lets an import (or require) of a .json file resolve, and gives the result the type of the file's contents: { "port": 8080 } becomes { port: number }. A typo in a property name is then an error like any other.
In TypeScript 5.9 it is on by default when module is nodenext, node20 or preserve, or when moduleResolution is bundler, which covers the setups on this site. With module set to node16, node18 or an es version alone, write it yourself.
At a glance
| Write | Usually nothing: nodenext and bundler turn it on. With other module settings, write "resolveJsonModule": true |
|---|---|
| On the command line | --resolveJsonModule |
| Type | boolean |
| Default in TypeScript 5.9 | false (on when module is nodenext, node20 or preserve, or moduleResolution is bundler) |
| TypeScript's description | Enable importing .json files. |
The description is quoted from TypeScript's own option list (Apache-2.0); see the notices.
Examples
import config from "./config.json" with { type: "json" };
console.log(`Listening on ${config.hots}:${config.port}`);error TS2339: Property 'hots' does not exist on type '{ port: number; host: string; }'.jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": [
"*.js"
]
} import config from "./config.json";error TS2732: Cannot find module './config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.
console.log(config.port);jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "esnext",
"types": [],
"moduleResolution": "bundler",
"resolveJsonModule": false
},
"include": [
"*.js"
]
} ES modules need the json import attribute
Node.js loads a JSON file from an ES module only with an import attribute: import config from "./config.json" with { type: "json" };. Under module: "nodenext", the checker holds you to it and reports a JSON import without one (TS1543). CommonJS files load JSON with require("./config.json") and need no attribute.
import config from "./config.json";error TS1543: Importing a JSON file into an ECMAScript module requires a 'type: "json"' import attribute when 'module' is set to 'NodeNext'.
console.log(config.port);jsconfig.json for this example
{
"compilerOptions": {
"checkJs": true,
"noEmit": true,
"strict": true,
"target": "es2022",
"module": "nodenext",
"types": []
},
"include": [
"*.js"
]
} What type a JSON import gets
TypeScript reads the file and widens the values: strings become string, numbers number, arrays of mixed values a union. It does not keep literal values, so "port": 8080 is number, not 8080. To type a config more precisely, annotate the import's use with a @type or check it with @satisfies.
Gotchas
- A big JSON file is read and typed on every check. For large data files that you import, a JSDoc
@typeon a value read withfscan be faster. - The typed JSON is the file as it is on disk when you check. A JSON file that changes at deploy time can differ from what was checked.
Questions
Why do I get TS2732 for a JSON import?
Your module and moduleResolution do not turn resolveJsonModule on (for example module: "node18", or a bundler setup that sets it to false). Add "resolveJsonModule": true.
Sources
- TSConfig Reference: resolveJsonModule · TypeScript
- TypeScript 2.9 release notes · TypeScript handbook
- Modules: ECMAScript modules, JSON modules · Node.js docs
Last reviewed 20 October 2026.