How to fix Failed to compile: SyntaxError: Unexpected token < (JSX) in React
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.
Quick fix
Fixes Failed to compile: SyntaxError: Unexpected token < (JSX)
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}- Verify your Babel configuration includes React preset
- Install missing Babel dependencies
- Check webpack configuration for babel-loader
- Fix linked library or monorepo JSX handling
{"presets": ["@babel/preset-env","@babel/preset-react"]}Failed to compile: SyntaxError: Unexpected token < (JSX)
What this error means
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.
Typical symptoms
- Build fails with 'Failed to compile' message in terminal
- Browser shows blank page or compilation error overlay
- Error specifically mentions 'Unexpected token <' or other JSX syntax
- Works in one part of the app but fails when importing from linked libraries
- Happens after ejecting Create React App or modifying webpack config
- Test files fail with JSX syntax errors in Jest
Common causes
- Babel preset for React (@babel/preset-react) is missing or not configured correctly
- Webpack is not processing .jsx files through babel-loader
- Importing components from a linked library or monorepo that Babel is excluding
- node_modules exclusion in babel-loader is blocking required transformations
- File extension mismatch (.jsx files not being resolved by webpack)
- Incorrect or missing .babelrc or babel.config.js configuration
- Ejected Create React App with modified webpack config that broke JSX handling
How to fix "Failed to compile: SyntaxError: Unexpected token < (JSX)"
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
Advanced notes
### 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.
Frequently asked questions
- What does "Failed to compile: SyntaxError: Unexpected token < (JSX)" mean?
- 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. 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.
- How do I fix "Failed to compile: SyntaxError: Unexpected token < (JSX)"?
- 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.
- What causes "Failed to compile: SyntaxError: Unexpected token < (JSX)"?
- Babel preset for React (@babel/preset-react) is missing or not configured correctly Webpack is not processing .jsx files through babel-loader Importing components from a linked library or monorepo that Babel is excluding
- Is the "Failed to compile: SyntaxError: Unexpected token < (JSX)" error serious?
- Yes. This is a high-severity error that usually blocks work until it is fixed, but the steps above resolve it.
Official resources & further reading
- 📚React Official Documentation
- 📖Babel - @babel/plugin-transform-react-jsx(Official Docs)
- 📖Webpack - babel-loader documentation(Official Docs)
- 🐙
- 🐙
- 🐙
- 📝