This error occurs when your build configuration is not properly set up to handle JSX syntax. JSX requires explicit configuration in your bundler, Babel setup, or TypeScript compiler to be transformed into valid JavaScript code that browsers can understand.
JSX is a special syntax that looks like HTML/XML but must be transformed into JavaScript function calls before the code runs. When your build tool (Webpack, Babel, TypeScript, esbuild, or Vite) is not configured to process JSX, it treats the syntax as invalid JavaScript and throws this error. The error typically occurs during the build process, in tests, or when loading the file.
Identify which tool is processing your code:
- Create React App / Next.js: These have JSX built-in, so the error is unusual
- Webpack: Check webpack.config.js for jsx loader
- esbuild: Check build configuration for jsx: 'automatic' or 'transform'
- Vite: Needs @vitejs/plugin-react
- TypeScript: Check tsconfig.json for jsx option
- Jest: Check jest.config.js or package.json jest section
Update your tsconfig.json compilerOptions:
{
"compilerOptions": {
"jsx": "react-jsx"
}
}Common jsx options:
- "react-jsx" - React 17+ automatic transform (recommended)
- "react" - Classic React transform (requires import React)
- "preserve" - Don't transform, let another tool handle it
Install the required preset:
npm install --save-dev @babel/preset-reactUpdate your .babelrc or babel.config.js:
{
"presets": [
[
"@babel/preset-react",
{
"runtime": "automatic"
}
]
]
}For TypeScript with Babel, include @babel/preset-typescript:
{
"presets": [
"@babel/preset-env",
"@babel/preset-typescript",
[
"@babel/preset-react",
{ "runtime": "automatic" }
]
]
}Add JSX loader to your esbuild configuration:
const esbuild = require('esbuild');
esbuild.build({
entryPoints: ['src/index.jsx'],
loader: {
'.jsx': 'jsx',
'.tsx': 'tsx'
},
jsx: 'automatic',
outfile: 'dist/bundle.js'
});Or for a craco wrapper around Create React App:
module.exports = {
webpack: {
configure: (webpackConfig) => {
const jsxRule = webpackConfig.module.rules.find(
(rule) => rule.test && rule.test.test('file.jsx')
);
if (jsxRule) {
jsxRule.loader = 'esbuild-loader';
jsxRule.options = { loader: 'tsx', target: 'es2015' };
}
return webpackConfig;
}
}
};Update your jest.config.js or package.json jest section:
module.exports = {
preset: 'ts-jest',
testEnvironment: 'jsdom',
moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx'],
globals: {
'ts-jest': {
tsconfig: {
jsx: 'react-jsx'
}
}
},
transform: {
'^.+\\.(ts|tsx)$': 'ts-jest',
'^.+\\.(js|jsx)$': 'babel-jest'
}
};Alternatively, use Babel for Jest:
{
"presets": [
"@babel/preset-react",
"@babel/preset-env"
]
}Install the React plugin:
npm install --save-dev @vitejs/plugin-reactUpdate your vite.config.js:
import react from '@vitejs/plugin-react';
import { defineConfig } from 'vite';
export default defineConfig({
plugins: [react()]
});Make sure you're using the right file extensions:
- JavaScript with JSX: Use .jsx extension
- TypeScript with JSX: Use .tsx extension
- JavaScript without JSX: Use .js extension
- TypeScript without JSX: Use .ts extension
Some tools may only process JSX in files with the correct extension. If you have JSX in a .js file, rename it to .jsx.
Sometimes cached build artifacts cause issues:
# Clear common cache directories
rm -rf node_modules/.cache
rm -rf .next # For Next.js
rm -rf dist # For custom builds
# Reinstall dependencies
npm install
# Rebuild your project
npm run buildReact 17+ Automatic Transform: React 17 introduced the automatic JSX transform, which doesn't require importing React in files that use JSX. Set your build tool to jsx: 'automatic' or jsx: 'react-jsx' in TypeScript to use this. This is the recommended approach for new projects.
Multiple Transform Versions: Ensure you're not mixing old and new JSX transforms in the same project. The classic transform (jsx: 'react') requires import React from 'react' in every file with JSX, while the automatic transform doesn't.
Monorepos and Workspaces: In monorepo setups, ensure each package has its own proper JSX configuration. Shared Babel or TypeScript configs should include JSX processing.
esbuild Specific: When using esbuild directly or through tools like craco, the loader must be set to either 'jsx' or 'tsx' depending on file type. Setting loader to 'ts' for .tsx files will cause this error.
Babel Caching: If you update your .babelrc, clear Babel cache with rm -rf node_modules/.cache/babel-loader.
Prop spreading could cause security issues
Prop spreading could cause security issues
Error: error:0308010C:digital envelope routines::unsupported
Error: error:0308010C:digital envelope routines::unsupported
React Hook "useEffect" is called conditionally. React Hooks must be called in the exact same order in every component render.
React Hook useEffect placed inside a condition
Hook can only be called inside the body of a function component
Hook can only be called inside the body of a function component
Rollup failed to resolve import during build
How to fix "Rollup failed to resolve import" in React