This error occurs when Babel cannot transform JSX syntax into JavaScript, typically due to missing presets, incorrect webpack configuration, or issues with linked libraries in Create React App projects.
This error indicates that your JavaScript build process encountered JSX syntax (like <Component />) but doesn't have the proper configuration to transform it into regular JavaScript. JSX is not valid JavaScript on its ownβit must be transpiled by Babel before browsers can execute it. In Create React App, this usually means that either: - The Babel loader is not processing certain files (common with linked libraries or monorepo setups) - Webpack configuration has been ejected and modified incorrectly - File extensions are not being resolved properly (.jsx files not recognized) The error message "Unexpected token <" specifically points to the opening angle bracket of a JSX element, which JavaScript parsers interpret as the less-than operator when JSX transformation is not working.
Check if you have a .babelrc, babel.config.js, or babel configuration in package.json. If you ejected Create React App, verify the configuration includes the React preset:
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}If you haven't ejected, Create React App handles this automatically. If the file is missing or incorrect, create/fix it.
If you've ejected or are using a custom setup, ensure you have the required packages:
npm install --save-dev @babel/core @babel/preset-env @babel/preset-react babel-loaderFor Create React App (not ejected), these are included by default, so this step is only needed for custom setups.
If you ejected Create React App, verify that your webpack.config.js includes babel-loader for JavaScript files:
module.exports = {
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['@babel/preset-env', '@babel/preset-react']
}
}
}
]
},
resolve: {
extensions: ['.js', '.jsx']
}
};The resolve.extensions ensures webpack recognizes .jsx files.
If you're importing from a linked library (npm link or yarn link) or working in a monorepo, the issue is often that babel-loader excludes node_modules. You need to explicitly include your linked packages:
// In webpack.config.js
{
test: /\.(js|jsx)$/,
exclude: /node_modules\/(?!(your-linked-package))/,
use: 'babel-loader'
}Alternatively, ensure your linked library is properly transpiled before being consumed. Export components from a built/dist folder rather than source.
Check the file mentioned in the error for JSX syntax issues:
- Ensure all JSX elements are properly closed: <Component /> or <Component></Component>
- Check for unescaped angle brackets in strings (use < and > or wrap in {})
- Verify imports are correct: import React from 'react' (required in React 16 and earlier)
// Correct
<div>Hello {name}</div>
// Incorrect - missing closing tag
<div>Hello {name}Build tools can cache incorrect configurations. Clear all caches and rebuild:
# Remove build artifacts and cache
rm -rf node_modules/.cache
rm -rf build
# Reinstall dependencies
rm -rf node_modules
npm install
# Rebuild
npm startFor Yarn users, also run: yarn cache clean
### Understanding Babel Transformations
Babel transforms JSX through a multi-stage process. The @babel/preset-react specifically handles JSX syntax by converting it to React.createElement() calls. For example:
<div className="app">Hello</div>
// Transforms to:
React.createElement('div', { className: 'app' }, 'Hello')### Monorepo and Symlinked Packages
In monorepo setups (Lerna, Yarn workspaces, npm workspaces), Create React App's webpack configuration excludes node_modules from Babel processing for performance. However, symlinked packages are technically in node_modules, so they're excluded too. Solutions include:
1. Use @nrwl/react or similar monorepo-aware tooling
2. Modify babel-loader's exclude to explicitly include your packages
3. Pre-transpile shared packages before consumption
### React 17+ JSX Transform
React 17 introduced a new JSX transform that doesn't require importing React. Update your Babel config to use it:
{
"presets": [
["@babel/preset-react", {
"runtime": "automatic"
}]
]
}This can resolve some edge cases where React import is missing but JSX is present.
### Ejecting Trade-offs
While ejecting Create React App gives you full control over webpack and Babel configs, it also means you're responsible for maintaining them. Consider alternatives like CRACO (Create React App Configuration Override) or react-app-rewired for non-ejected configuration modifications.
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