How to Fix cannot use jsx unless the '--jsx' flag is provided once and for all

How to Fix cannot use jsx unless the '--jsx' flag is provided once and for all

You’re staring at your screen. The terminal is bleeding red text, and VS Code is acting like it’s never seen a div tag in its life. You’ve just tried to run your React or SolidJS project, but TypeScript is throwing a fit: cannot use jsx unless the '--jsx' flag is provided. It’s annoying. It feels like the compiler is questioning your basic intelligence, but honestly, it’s usually just a tiny configuration gap or a workspace mismatch. This error essentially means TypeScript has encountered angle brackets—the <App /> variety—and has absolutely no idea what to do with them because you haven't told it how to transform that syntax into standard JavaScript.

Why TypeScript hates your JSX right now

Basically, browsers don't speak JSX. If you ship a file full of tags to Chrome or Safari, they’ll crash. TypeScript acts as the middleman that turns those tags into something readable, like React.createElement or a more modern optimization. When you see the message cannot use jsx unless the '--jsx' flag is provided, the compiler is saying, "I see what you're trying to do, but my settings are currently set to 'strict boring mode' where tags aren't allowed."

💡 You might also like: FCC Robocall Enforcement October 2025: Why Your Phone is Still Ringing

It’s often a case of the tsconfig.json file being ignored or misconfigured. Or, more commonly in 2026, your IDE is looking at one version of TypeScript while your build tool is looking at another. It happens to the best of us. You might have a perfectly valid file, but if TypeScript thinks it’s a plain .ts file instead of a .tsx file, or if the compiler options are missing the jsx property, you're stuck.

Hunting down the tsconfig.json

The fix is almost always inside your tsconfig.json. Look for the compilerOptions block. You need to add or update the jsx field. Back in the day, we used react, but nowadays, you’re likely looking for react-jsx or react-jsxdev.

If you're using React 17 or later, react-jsx is the way to go. It tells TypeScript to use the new JSX transform that doesn't require you to import React from 'react' at the top of every single file. This keeps your bundle smaller and your code cleaner. If you're working with a different library, like Preact or Solid, that value might be preserve, letting a tool like Vite or Babel handle the heavy lifting later in the pipeline.

The IDE Trap

Sometimes your config is perfect. You check the file, the flag is there, and yet the red squiggles remain. This is the "VS Code Ghost." Often, VS Code uses its own internal version of TypeScript rather than the one in your node_modules. Open a .tsx file, look at the bottom right corner of the window, and click on the TypeScript version number. Select "Use Workspace Version." This forces the editor to respect the specific rules and flags you've set for your project. It's a lifesaver.

What about the command line?

If you aren't using a config file and you're running the compiler manually (which is rare but happens), you literally have to pass the flag. tsc index.tsx --jsx react-jsx. But let's be real: nobody wants to type that every time. If you're seeing this error during a build process like Vite, Esbuild, or Webpack, it might be because the loader isn't passing the right context to the TypeScript engine.

Check your package.json. If your "main" or "types" entry points are pointing to the wrong places, or if you have multiple tsconfig files (like tsconfig.node.json and tsconfig.app.json), your editor might be getting confused about which rules apply to which file. Make sure your .tsx files are included in the include array of the correct config.

Real world breakdown of JSX options

  • preserve: Keeps the JSX as it is. Use this if you want another tool (like Babel) to do the transformation.
  • react: The old school way. Turns <div /> into React.createElement('div').
  • react-native: Keeps JSX but changes the extension to .js.
  • react-jsx: The modern standard. No React import needed.
  • react-jsxdev: Same as above but adds extra debugging info for development.

A common mistake is having a jsconfig.json and a tsconfig.json fighting for dominance. If you're in a TypeScript project, delete the jsconfig. It’s just noise. Also, check for a "files" or "include" property in your config. If your new component is in a folder like src/components/ui/ but your config only looks at src/, TypeScript will default to its factory settings for that file, which—you guessed it—doesn't include JSX support.

Nuances of Modern Frameworks

Modern setups like Next.js or Remix usually handle this for you. If you see this error in a Next.js project, it usually means your tsconfig.json was overwritten or you accidentally deleted the compilerOptions. Next.js actually monitors that file and will often try to fix it for you upon restart. Try killing your dev server and running npm run dev again. It’s the "turn it off and on again" of the web development world, but it actually works here because Next.js re-generates the necessary configuration if it detects it's broken.

Don't ignore the file extension either. You cannot use JSX in a .ts file. Period. It must be .tsx. I’ve spent twenty minutes debugging a config flag only to realize I forgot that one little 'x' at the end of the filename. It’s a humbling experience.

Actionable Steps to Clear the Error

Stop searching for complex solutions and do these four things in order. First, open tsconfig.json and ensure "jsx": "react-jsx" (or your framework's equivalent) exists inside compilerOptions. If it's missing, add it. Second, verify that your file extension is definitely .tsx. A .ts file will always throw this error regardless of your flags.

Third, restart your TS server. In VS Code, open the Command Palette (Cmd/Ctrl + Shift + P) and type "Restart TS Server." This clears the cache and forces the editor to re-read your config. Finally, if you're using a monorepo, make sure you aren't editing a file in one package while looking at the tsconfig of another. Ensure the root of your workspace is correctly set to the folder containing the config file.

Once these alignment issues are resolved, the compiler will finally understand that those tags aren't syntax errors, but the blueprints for your UI. Check your exclude block too; if you accidentally excluded your src folder, TypeScript will treat every file in it like a generic, unconfigured script. Clear those hurdles and you're back to building.