You import JSON files in TypeScript with a normal import statement once resolveJsonModule is on in your tsconfig. TypeScript then reads the file and infers a type for every property:
import config from "./store-config.json";
console.log(config.storeName);
I tested every example here in strict mode with TypeScript 7.0.2 and Node.js v22.22.2, and each output below is copied from my console.
We’ll cover the tsconfig settings, the TS2732 error, typing the data, ESM import attributes, require and reading JSON at runtime.
Import a JSON file with resolveJsonModule
Here’s the sample file every example reads, a small store config saved as store-config.json:
{
"storeName": "Cascade Outfitters",
"city": "Seattle",
"state": "WA",
"currency": "USD",
"freeShippingMin": 49.99,
"openedOn": "2026-03-02",
"featured": ["Trail Jacket", "Camp Mug", "Rain Shell"]
}
Turn on resolveJsonModule in tsconfig.json (I pass the same options as tsc flags):
{
"compilerOptions": {
"module": "commonjs",
"resolveJsonModule": true,
"esModuleInterop": true
}
}
import config from "./store-config.json";
console.log(`${config.storeName} (${config.city}, ${config.state})`);
console.log(`Free shipping over $${config.freeShippingMin.toFixed(2)}`);
console.log("Featured:", config.featured.join(", "));
Output:
Cascade Outfitters (Seattle, WA)
Free shipping over $49.99
Featured: Trail Jacket, Camp Mug, Rain Shell

Keep the ./ and the .json extension in the path. If you’d rather turn the data into a list, see converting JSON to an array in TypeScript.
Why does TypeScript say “Cannot find module ‘./file.json'”?
That’s error TS2732, and it means resolveJsonModule is off. TypeScript 7 already resolved my import with its default settings, so I switched the option off to reproduce what older tsconfig files show:
import config from "./store-config.json";
console.log(`${config.storeName} (${config.city}, ${config.state})`);
console.log(`Free shipping over $${config.freeShippingMin.toFixed(2)}`);
console.log("Featured:", config.featured.join(", "));
Compiler output:
json_off.ts(1,20): error TS2732: Cannot find module './store-config.json'. Consider using '--resolveJsonModule' to import module with '.json' extension.

--resolveJsonModule.Set "resolveJsonModule": true and the error is gone. If it still fails, check the path and that the file sits inside rootDir; fixing Cannot find module in TypeScript walks through the other causes.
How TypeScript types imported JSON
You don’t write an interface for an imported file. TypeScript reads the JSON and infers string, number and string[], which typeof config turns into a reusable type:
import config from "./store-config.json";
type StoreConfig = typeof config;
function qualifies(orderTotal: number, store: StoreConfig): boolean {
return orderTotal >= store.freeShippingMin;
}
console.log("$52.40 order ships free:", qualifies(52.4, config));
console.log("$18.75 order ships free:", qualifies(18.75, config));
const minimum: string = config.freeShippingMin;
Compiler output:
json_typed.ts(12,7): error TS2322: Type 'number' is not assignable to type 'string'.
The last line fails on purpose: the inferred type knows freeShippingMin is a number. Need your own named type instead? Read converting JSON to a TypeScript interface.
Import JSON in ES modules with with { type: “json” }
Node.js loads JSON into an ES module only with the type: "json" attribute. With module set to nodenext, an .mts file without it fails with TS1543. Add it to static imports and to the options of a dynamic import():
import config from "./store-config.json" with { type: "json" };
console.log("Static import:", config.storeName, "since", config.openedOn);
const { default: lazy } = await import("./store-config.json", { with: { type: "json" } });
console.log("Dynamic import:", lazy.featured.length, "featured items");
Output:
Static import: Cascade Outfitters since 2026-03-02
Dynamic import: 3 featured items

import() load the same JSON file in Node.js.Import attributes need module set to esnext, nodenext or preserve (tsc reports TS2823 otherwise). Older tutorials show assert; use with. For config values that differ per machine, see environment variables in TypeScript.
Load JSON with require in CommonJS
In a CommonJS project, import ... = require() keeps the inferred types. A bare const x = require() needs @types/node and gives you any:
import config = require("./store-config.json");
console.log(config.storeName, "uses", config.currency);
Output:
Cascade Outfitters uses USD
Skip as casts on that any value; they hide mistakes. Type casting in TypeScript explains when a cast is safe.
Read a JSON file at runtime with fs and JSON.parse
Imports are fixed at build time, so read files that change with fs. JSON.parse() returns any, so I store it as unknown and check it with a type guard, as covered in TypeScript type narrowing:
import { readFileSync } from "node:fs";
import { join } from "node:path";
interface StoreConfig {
storeName: string;
freeShippingMin: number;
featured: string[];
}
function isStoreConfig(value: unknown): value is StoreConfig {
const v = value as StoreConfig;
return typeof v?.storeName === "string" && typeof v.freeShippingMin === "number"
&& Array.isArray(v.featured);
}
const raw: unknown = JSON.parse(readFileSync(join(__dirname, "store-config.json"), "utf8"));
if (isStoreConfig(raw)) {
console.log(`${raw.storeName}: free shipping over $${raw.freeShippingMin.toFixed(2)}`);
} else {
console.log("store-config.json has the wrong shape");
}
Output:
Cascade Outfitters: free shipping over $49.99

freeShippingMin.TypeScript 7 doesn’t load @types packages automatically, so I installed @types/node and passed --types node. In a tsconfig, that’s "types": ["node"].
Which way to import JSON files in TypeScript should you use?
| Method | Best for | Typed? |
|---|---|---|
import + resolveJsonModule | Bundlers and CommonJS projects | Yes, inferred |
import ... with { type: "json" } | ES modules running in Node.js | Yes, inferred |
import x = require() | Older CommonJS code | Yes, inferred |
fs.readFileSync + JSON.parse | Files that change at runtime | No, use a guard |
These related TypeScript tutorials pick up where this one stops:
- Check if an object matches an interface
- satisfies vs as in TypeScript
- When the any type is (and isn’t) OK
- Compare strings in TypeScript
Frequently asked questions
How do I import a JSON file in TypeScript?
Set "resolveJsonModule": true in tsconfig.json, then write import data from "./data.json". In Node.js ES modules, add with { type: "json" }.
Why do I get error TS2732?
TS2732 means TypeScript can’t resolve a .json import because resolveJsonModule is off. Turn it on and check the relative path.
Do I need an interface for imported JSON?
No. TypeScript infers the type from the file. Use typeof data to reuse it, or write an interface when the JSON is read at runtime.
Should I use assert or with for JSON imports?
Use with { type: "json" }. The assert keyword is the older proposal syntax.
Can I import JSON without resolveJsonModule?
Yes, read it at runtime with fs.readFileSync and JSON.parse, then validate the result with a type guard.
Where is resolveJsonModule documented?
See resolveJsonModule in the official TypeScript tsconfig reference.

Bijay Kumar is a 13-time Microsoft MVP with more than 18 years in software development, and the founder of Python Guides and TSinfo Technologies. He star