This TypeScript error occurs when the 'jsx' compiler option in tsconfig.json is set without a valid value. The jsx option controls how JSX syntax is transformed and must be set to one of several valid values like 'preserve', 'react', 'react-jsx', or 'react-native'.
The "'jsx' option requires a value" error appears when TypeScript encounters an invalid or missing value for the 'jsx' compiler option in your tsconfig.json configuration file. This option is essential when working with React, Vue, or other frameworks that use JSX syntax. The jsx option tells TypeScript how to handle JSX syntax in your code: - Should it transform JSX to regular JavaScript function calls? - Should it preserve JSX for a bundler to handle? - Should it use the new JSX transform introduced in React 17+? When this option is set incorrectly (like an empty string, wrong value, or missing entirely), TypeScript cannot determine how to process JSX elements in your .tsx files, resulting in this compilation error.
Open your tsconfig.json file and ensure the jsx option has one of these valid values:
{
"compilerOptions": {
// For React projects (most common):
"jsx": "react-jsx", // React 17+ with new JSX transform (recommended)
"jsx": "react", // Classic React transform (pre-React 17)
// For other use cases:
"jsx": "preserve", // Keep JSX for bundler to transform
"jsx": "react-native", // React Native projects
// For testing/debugging:
"jsx": "react-jsxdev" // React 17+ with dev mode
}
}Recommended values:
- `"react-jsx"`: Modern React projects (React 17+)
- `"react"`: Legacy React projects (React 16 and earlier)
- `"preserve"`: When using a bundler like Vite or webpack with JSX plugins
After updating, restart your TypeScript server:
- VS Code: Press Cmd/Ctrl + Shift + P, then "TypeScript: Restart TS Server"
- Terminal: npx tsc --noEmit to test compilation
Check for syntax errors in your tsconfig.json that might prevent TypeScript from reading the jsx value:
// WRONG - missing quotes or trailing comma
{
"compilerOptions": {
"jsx": react-jsx, // Missing quotes around value
"target": "es2020", // Trailing comma (valid in JSON5 but not strict JSON)
}
}
// CORRECT
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "es2020"
}
}Common syntax issues to check:
1. Missing quotes around string values
2. Trailing commas in objects/arrays (invalid in strict JSON)
3. Comments (JSON doesn't support comments, use JSON5 if needed)
4. Missing braces or brackets
5. Incorrect file extension (must be .json, not .js or .ts)
Validate your JSON with:
# Check JSON syntax
npx jsonlint tsconfig.json
# Or use Node.js
node -e "JSON.parse(require('fs').readFileSync('tsconfig.json', 'utf8'))" && echo "Valid JSON"TypeScript can inherit settings from multiple configuration files. Check for:
1. Base tsconfig.json: tsconfig.base.json or tsconfig.json in parent directories
2. Extends property: Your tsconfig might extend another config:
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx" // This overrides the base config
}
}3. Project references: In monorepos, check referenced projects:
{
"references": [
{ "path": "./packages/ui" },
{ "path": "./packages/utils" }
]
}To debug which configuration is being used:
# Show effective configuration
npx tsc --showConfig
# Or compile with verbose output
npx tsc --extendedDiagnosticsIf using extends, ensure the base config doesn't have an invalid jsx value. You can override it in your main tsconfig.json.
Some jsx values require newer TypeScript versions:
| jsx value | Minimum TypeScript | Purpose |
|-----------|-------------------|---------|
| "react-jsx" | 4.1+ | React 17+ new JSX transform |
| "react-jsxdev" | 4.1+ | React 17+ dev mode |
| "preserve" | 1.6+ | Keep JSX for bundler |
| "react" | 1.6+ | Classic React transform |
| "react-native" | 1.6+ | React Native |
Check your TypeScript version:
npx tsc --version
# or
npm list typescriptUpdate if needed:
# Update to latest
npm install --save-dev typescript@latest
# Or specific version
npm install --save-dev [email protected]After updating, clear any cached TypeScript data:
# Delete TypeScript build cache
rm -rf node_modules/.cache
# Restart IDE TypeScript server
# In VS Code: Cmd/Ctrl + Shift + P → "TypeScript: Restart TS Server"Different frameworks require different jsx settings:
React (modern):
{
"compilerOptions": {
"jsx": "react-jsx",
"lib": ["dom", "dom.iterable", "esnext"],
"moduleResolution": "node"
}
}React (legacy):
{
"compilerOptions": {
"jsx": "react",
"lib": ["dom", "dom.iterable", "esnext"]
}
}Vue with JSX:
{
"compilerOptions": {
"jsx": "preserve", // Vue handles JSX transformation
"lib": ["dom", "esnext"]
}
}React Native:
{
"compilerOptions": {
"jsx": "react-native",
"moduleResolution": "node",
"target": "esnext"
}
}Next.js (automatically configured):
Next.js handles TypeScript configuration internally. If you see this error in Next.js:
1. Check next.config.js for custom TypeScript settings
2. Ensure you're not manually overriding tsconfig.json incorrectly
3. Run npm run build to see Next.js's TypeScript diagnostics
Create a minimal tsconfig.json to isolate the issue:
// tsconfig.minimal.json
{
"compilerOptions": {
"jsx": "react-jsx",
"target": "es2020",
"module": "commonjs",
"strict": true
},
"include": ["src/**/*"]
}Test compilation:
# Compile with minimal config
npx tsc --project tsconfig.minimal.json --noEmit
# If this works, your main tsconfig has other issues
# Compare with your actual tsconfig:
npx tsc --showConfig > actual-config.json
npx tsc --project tsconfig.minimal.json --showConfig > minimal-config.json
diff actual-config.json minimal-config.jsonCommon differences to check:
1. Multiple jsx declarations in extended configs
2. Conflicting compiler options
3. Incorrect file inclusions/exclusions
4. Environment-specific overrides (tsconfig.production.json, etc.)
Once identified, fix the issue in your main tsconfig.json and delete the minimal test file.
### JSX Transform Modes Explained
react-jsx (React 17+):
- Automatically imports React when needed (no need for import React from 'react')
- Uses jsx() and jsxs() runtime functions
- Better tree-shaking and performance
- Requires React 17+ and TypeScript 4.1+
react (Classic):
- Transforms JSX to React.createElement() calls
- Requires import React from 'react' in every file
- Compatible with all React versions
- Larger bundle size due to React import
preserve:
- Keeps JSX syntax unchanged in output
- Bundler (webpack, Vite, esbuild) must transform JSX
- Used with frameworks that have custom JSX transforms (Vue, SolidJS)
- Output files have .jsx extension
react-native:
- Similar to "preserve" but emits .js files
- React Native's Metro bundler handles transformation
- For React Native projects only
### Migration from react to react-jsx
If upgrading from React 16 to React 17+:
1. Update React to 17+:
npm install react@17 react-dom@17
# or
npm install react@18 react-dom@182. Change tsconfig.json:
{
"compilerOptions": {
"jsx": "react-jsx" // Changed from "react"
}
}3. Remove unnecessary React imports:
// BEFORE (with "react")
import React from 'react';
const Component = () => {
return <div>Hello</div>;
};
// AFTER (with "react-jsx")
// No React import needed!
const Component = () => {
return <div>Hello</div>;
};4. Update ESLint configuration if using react/jsx-runtime rules.
### Framework-Specific Considerations
Next.js:
- Automatically configures TypeScript with jsx: "preserve"
- Uses SWC for compilation (faster than tsc)
- Custom tsconfig.json may conflict with Next.js defaults
- Check next-env.d.ts for TypeScript declarations
Vite:
- Uses esbuild for development, tsc for type checking
- Configure with jsx: "preserve" or jsx: "react-jsx"
- Vite's React plugin handles JSX transformation
Create React App (CRA):
- Uses jsx: "react-jsx" in template
- Ejected configs may need updating
- CRA 5+ uses React 18 by default
### Debugging Configuration Issues
Use TypeScript's diagnostic commands:
# Show all configuration files being read
npx tsc --listFiles
# Show compiler options in effect
npx tsc --showConfig
# Generate trace of configuration resolution
npx tsc --generateTrace ./trace
# Check for specific option
npx tsc --diagnostics | grep -i jsx### Common Pitfalls
1. JSON vs JSON5: Some tools allow JSON5 (with comments), but TypeScript requires strict JSON
2. Windows vs Unix paths: Use forward slashes (/) for consistency
3. Monorepo complexity: Each package may need its own tsconfig with proper references
4. IDE caching: Restart TypeScript server after configuration changes
5. Node modules: Delete node_modules/.cache if configuration seems stuck
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