This TypeScript error occurs when you try to import JSON files without enabling the resolveJsonModule compiler option. TypeScript needs explicit configuration to allow JSON imports, which are treated as modules with default exports containing the parsed JSON data.
The "Option 'resolveJsonModule' is not set but .json files are imported" error appears when TypeScript encounters import statements for .json files but the resolveJsonModule compiler option is not enabled in tsconfig.json. TypeScript treats JSON files differently from regular TypeScript/JavaScript files. By default, TypeScript doesn't allow importing JSON files as modules because: 1. JSON files don't contain executable code 2. They need to be parsed at compile time to provide type information 3. The import behavior differs between CommonJS and ES module systems When resolveJsonModule is enabled, TypeScript: - Allows import statements for .json files - Provides type checking for the imported JSON structure - Compiles the import to appropriate runtime code (require() for CommonJS, import for ES modules) - Enables JSON files to be treated as modules with a default export containing the parsed data This error is common when migrating JavaScript projects to TypeScript or when adding JSON configuration files to a TypeScript project.
Add or update the resolveJsonModule option in your tsconfig.json:
{
"compilerOptions": {
"resolveJsonModule": true,
// Other options...
}
}For CommonJS projects (Node.js, webpack with CommonJS):
{
"compilerOptions": {
"resolveJsonModule": true,
"module": "commonjs",
"esModuleInterop": true
}
}For ES Module projects (Node.js with "type": "module", modern bundlers):
{
"compilerOptions": {
"resolveJsonModule": true,
"module": "esnext",
"moduleResolution": "node"
}
}After saving tsconfig.json, restart your TypeScript server:
- In VS Code: Press Ctrl/Cmd + Shift + P, then "TypeScript: Restart TS Server"
- Or restart your IDE/editor
The resolveJsonModule option was introduced in TypeScript 2.9. Check your version:
# Check TypeScript version
npx tsc --version
# Or check package.json
npm list typescriptIf you're using TypeScript < 2.9, upgrade:
# Update TypeScript
npm install --save-dev typescript@latest
# Or for a specific version
npm install --save-dev typescript@^4.0.0Minimum recommended versions:
- TypeScript 4.0+ for modern features
- TypeScript 3.0+ for basic resolveJsonModule support
After upgrading, verify the option works:
npx tsc --showConfig | grep resolveJsonModuleEnsure you're using the correct import syntax for JSON files:
// CORRECT - Default import for JSON files
import config from "./config.json";
import packageJson from "../package.json";
// CORRECT - With type annotation (recommended)
import type Config from "./config.json";
import config from "./config.json";
// CORRECT - Destructuring from default import
import { version, name } from "../package.json";
// WRONG - Named imports (JSON files only have default export)
import { version } from "../package.json"; // Error: Module has no exported member 'version'
// CORRECT alternative for named access
import pkg from "../package.json";
const { version, name } = pkg;
// WRONG - Import assertion syntax (TypeScript 4.5+)
import config from "./config.json" assert { type: "json" }; // Not needed with resolveJsonModule
// CORRECT - Simple import
import config from "./config.json";JSON files are treated as modules with a default export containing the parsed JSON object.
If you have multiple tsconfig files, ensure resolveJsonModule is set in the correct one:
# Find all tsconfig files in project
find . -name "tsconfig*.json" -type f
# Common tsconfig files:
# - tsconfig.json (main config)
# - tsconfig.app.json (app-specific)
# - tsconfig.node.json (Node.js specific)
# - tsconfig.build.json (build-specific)
# - tsconfig.test.json (test-specific)If using extends:
// tsconfig.base.json (base configuration)
{
"compilerOptions": {
"resolveJsonModule": true,
// Other shared options...
}
}
// tsconfig.json (extends base)
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
// Can override or add options
},
"include": ["src/**/*"]
}Verify which tsconfig is being used:
# Show active configuration
npx tsc --showConfig
# Compile with specific tsconfig
npx tsc -p tsconfig.app.jsonEnsure your module resolution settings work with JSON files:
For Node.js projects:
{
"compilerOptions": {
"resolveJsonModule": true,
"moduleResolution": "node",
"module": "commonjs",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true
}
}For ES Modules (Node.js with "type": "module" in package.json):
{
"compilerOptions": {
"resolveJsonModule": true,
"moduleResolution": "node16",
"module": "node16"
}
}For bundlers (webpack, Vite, esbuild):
{
"compilerOptions": {
"resolveJsonModule": true,
"moduleResolution": "bundler",
"module": "esnext"
}
}If using path aliases, ensure they work with JSON files:
{
"compilerOptions": {
"resolveJsonModule": true,
"baseUrl": "./src",
"paths": {
"@config/*": ["config/*"]
}
}
}Then import:
import config from "@config/app.json";Different build tools and environments may need additional configuration:
Webpack: Already handles JSON imports by default, but TypeScript needs resolveJsonModule for type checking.
Vite: Works with resolveJsonModule, but may need explicit configuration for JSON imports in some cases:
// vite.config.js
export default {
// Vite handles JSON imports automatically
}Node.js with ES Modules: Ensure package.json has "type": "module":
{
"name": "my-project",
"type": "module",
"scripts": {
"start": "node --loader ts-node/esm src/index.ts"
}
}Testing frameworks (Jest): Configure Jest to handle JSON imports:
// jest.config.js
module.exports = {
transform: {
'^.+\.tsx?$': 'ts-jest',
},
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json'],
};TypeScript with Node.js and ts-node:
# Install ts-node
npm install --save-dev ts-node
# Run with ts-node
npx ts-node src/index.ts
# Or configure in package.json
{
"scripts": {
"start": "ts-node src/index.ts"
}
}### JSON Schema Validation
While resolveJsonModule provides type checking for JSON imports, consider adding JSON schema validation for runtime safety:
import config from "./config.json";
import { validate } from "jsonschema";
const schema = {
type: "object",
properties: {
port: { type: "number" },
host: { type: "string" },
},
required: ["port", "host"],
};
const result = validate(config, schema);
if (!result.valid) {
throw new Error(`Invalid config: ${result.errors}`);
}### Dynamic JSON Imports
For dynamic JSON imports (loading JSON at runtime), use import():
// Dynamic import with type assertion
const config = await import("./config.json") as { default: ConfigType };
// Or with fetch for remote JSON
const response = await fetch("/api/config.json");
const config = await response.json();### JSON Import Limitations
1. No tree-shaking: Entire JSON file is included in bundle
2. No hot reload: Changes to JSON files may not trigger hot reload
3. Large files: Consider splitting large JSON files or using lazy loading
4. Type definitions: For complex JSON structures, create interface definitions:
// types/config.d.ts
export interface AppConfig {
port: number;
host: string;
features: {
analytics: boolean;
logging: boolean;
};
}
// usage
import config from "./config.json";
const typedConfig: AppConfig = config;### Alternative: JSON as Raw String
If you need the raw JSON string (not parsed), use raw-loader (webpack) or similar:
// With webpack raw-loader
import rawJson from "!!raw-loader!./config.json";
// Parse manually when needed
const config = JSON.parse(rawJson);### TypeScript 4.5+ Import Assertions
TypeScript 4.5+ supports import assertions, but resolveJsonModule is still recommended:
// With import assertions (TypeScript 4.5+)
import config from "./config.json" assert { type: "json" };
// Still need resolveJsonModule for type checking### Common Pitfalls
1. Circular references: JSON files can't import other JSON files
2. Comments in JSON: Standard JSON doesn't support comments; use JSONC (JSON with Comments) and a parser that supports it
3. Environment-specific JSON: Consider using .json.template files and generating environment-specific JSON at build time
4. Security: Never import user-provided JSON; validate and sanitize first
### Performance Considerations
- Bundle size: Each JSON import adds to bundle size
- Parse time: Large JSON files increase parse time
- Memory: Parsed JSON stays in memory
- Alternatives: For large datasets, consider:
- Splitting into multiple files
- Using a database
- Lazy loading with import()
- Streaming parsers for very large files
Function expression requires a return type
Function expression requires a return type
Value of type 'string | undefined' is not iterable
How to fix "Value is not iterable" in TypeScript
Type 'undefined' is not assignable to type 'string'
How to fix "Type undefined is not assignable to type string" in TypeScript
Type narrowing from typeof check produces 'never'
How to fix "Type narrowing produces never" in TypeScript
Type parameter 'T' has conflicting constraints
How to fix "Type parameter has conflicting constraints" in TypeScript