The Stack Overflow question Cannot use JSX unless the '--jsx' flag is provided has 569 upvotes and 627,677 views because the error survives the obvious fix. A developer sets "jsx": "react" in compilerOptions of tsconfig.json, restarts nothing, and the editor still underlines every .tsx file with Cannot use JSX unless the '--jsx' flag is provided. The fix is usually to select the workspace TypeScript version in VS Code and restart the IDE, or to let react-scripts set react-jsx for React 17+.
The error, decoded
You see the error in the VS Code Problems pane or as a red squiggle on the first JSX element in a .tsx file. The message is:
Cannot use JSX unless the '--jsx' flag is provided
It fires even when tsconfig.json already contains "jsx": "react" inside compilerOptions. The key property is compilerOptions.jsx. The question's tsconfig is a typical example:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"allowJs": true,
"checkJs": false,
"jsx": "react",
"outDir": "./build",
"rootDir": "./lib",
"removeComments": true,
"noEmit": true,
"pretty": true,
"skipLibCheck": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true
},
"include": [
"./lib/**/*"
],
"exclude": [
"node_modules"
]
}
The developer also uses Babel 7 with the env, react, and typescript presets, so the code compiles at build time. The editor still reports the flag error because the TypeScript language service has not reloaded the config or is using a different TypeScript version. The error is not a build failure; it is an editor-state problem.
Why TypeScript doesn't pick up the tsconfig change
The root cause is not the jsx value itself; it's that the editor's TypeScript server is not reading the compilerOptions.jsx you set. VS Code ships with its own TypeScript version, while the project has its own TypeScript copy in node_modules. When the editor uses the built-in version, it may not understand the react-jsx value or may cache the old tsconfig.json. The command palette option TypeScript: Select a TypeScript Version... only appears when a .tsx file is open, which hides the fix from anyone editing only tsconfig.json.
A second cause appears in React 17+ projects created with react-scripts. Running npm start prints "The following changes are being made to your tsconfig.json file: - compilerOptions.jsx must be react-jsx (to support the new JSX transform in React 17)". react-scripts rewrites compilerOptions.jsx from react to react-jsx to match the automatic JSX transform. If you manually set react, the next npm start reverts it, and the editor may still show the old error until the language service reloads.
This is the same stale-config problem covered in Fix tsconfig Paths Not Working in Next.js. If your include pattern misses .tsx files, the compiler never sees them; see Force tsc to Ignore node_modules: Fix TS Errors for include/exclude details.
The fix: select the workspace TypeScript version and restart
- Open any
.tsxfile in VS Code. The command is hidden otherwise. - Open the command palette with
Ctrl+Shift+P(Windows/Linux) orCmd+Shift+P(Mac). - Type
TypeScript: Select a TypeScript Version...and choose it. - Select
Use workspace Version. - Restart VS Code.
After restart, the editor uses the project's TypeScript version from node_modules, which reads the jsx setting correctly. If react-scripts keeps overriding the setting, do not fight it. Let it set "jsx": "react-jsx". The correct tsconfig for a React 17+ project looks like this:
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"allowJs": true,
"checkJs": false,
"jsx": "react-jsx",
"outDir": "./build",
"rootDir": "./lib",
"removeComments": true,
"noEmit": true,
"pretty": true,
"skipLibCheck": true,
"strict": true,
"moduleResolution": "node",
"esModuleInterop": true
},
"include": [
"./lib/**/*"
],
"exclude": [
"node_modules"
]
}
The only change from the original file is the jsx value:
{
"compilerOptions": {
- "jsx": "react"
+ "jsx": "react-jsx"
}
}
That single change addresses the React 17 automatic JSX transform, but the editor still needs the workspace TypeScript version to stop showing the flag error.
Two patterns that still trip you up
Variant A — react-scripts rewrites jsx to react-jsx
If you set "jsx": "react" and run npm start, react-scripts prints the override message and changes the file. The editor may still show the flag error until you reload the TypeScript server. The fix is to accept react-jsx and select the workspace TypeScript version. The new JSX transform changes how TypeScript emits JSX; if you later hit type errors in components, JSX.Element vs ReactNode vs ReactElement: TS2322 Fix covers the type side.
Variant B — Babel compiles but the editor still complains
The question's setup uses Babel 7 with the @babel/preset-env, @babel/preset-react, and @babel/preset-typescript presets, so the build succeeds. The editor error is purely a language-service problem. The fix is the same: select the workspace TypeScript version and restart. Do not add "include": [] as a workaround; the question already has a correct include pattern, and emptying it hides real files from the compiler.
Variant C — ESLint adds noise from import rules
If you have eslint-plugin-import, eslint-config-airbnb-base, or eslint-config-airbnb-typescript in the project, a misconfigured parser may not recognize .tsx files, producing red underlines that look like TypeScript errors. Configure ESLint with:
parser: '@typescript-eslint/parser'settings: { 'import/resolver': { typescript: {} } }- Extends
airbnb-typescriptonly after installing its peer dependencies (eslint-config-airbnb-base,@typescript-eslint/eslint-plugin,@typescript-eslint/parser) and enabling TypeScript support.
Without these settings, eslint-plugin-import can report import/resolver errors that distract from the real --jsx flag issue. Keep ESLint aligned with the workspace TypeScript version to avoid false positives.
Confirm it's resolved
After restarting VS Code with the workspace TypeScript version selected, open the .tsx file that showed the error. The red squiggle under the JSX element should disappear. The Problems pane should no longer list Cannot use JSX unless the '--jsx' flag is provided.
If you are using react-scripts, run npm start again. The terminal should show the override message once, then the dev server starts without the editor error. The tsconfig file should now contain "jsx": "react-jsx".
If the error persists, check that the .tsx file is inside the include glob. The question's include is ./lib/**/*, so a file outside lib is not part of the TypeScript project. Move the file or widen the glob.
FAQ
How do I fix 'Cannot use JSX unless the '--jsx' flag is provided' in TypeScript?
Select the workspace TypeScript version in VS Code: open a .tsx file, run TypeScript: Select a TypeScript Version... from the command palette, choose Use workspace Version, and restart the IDE. If react-scripts is present, let it set "jsx": "react-jsx".
Why does the error persist after adding "jsx": "react" to tsconfig.json?
VS Code often uses its built-in TypeScript version instead of the project's workspace version, so the tsconfig change is not picked up until you select Use workspace Version and restart. The command only appears when a .tsx file is open.
What is the difference between "jsx": "react" and "jsx": "react-jsx"?
"jsx": "react" emits React.createElement calls and requires import React from 'react'. "jsx": "react-jsx" uses the React 17 automatic JSX transform, which does not require the React import. react-scripts sets react-jsx automatically.
Related
- JSX.Element vs ReactNode vs ReactElement: TS2322 Fix
- Fix tsconfig Paths Not Working in Next.js
- Force tsc to Ignore node_modules: Fix TS Errors
- Fix "Parsing error: Cannot find module next/babel"
Originally published at https://www.iloveblogs.blog
Top comments (0)