The React renderer failed to parse your JavaScript because the JavaScript engine encountered syntax it didn’t understand, specifically JSX, which isn’t standard JavaScript.

This typically happens when your build process is configured to expect plain JavaScript but it’s receiving JSX, which requires a transpilation step to convert it into standard JavaScript that browsers can execute.

Here are the common causes and how to fix them:

  1. Missing or Misconfigured Babel Loader in Webpack:

    • Diagnosis: Check your webpack.config.js file. Look for a module.rules entry that handles .js or .jsx files. If it’s missing, or if it doesn’t include babel-loader with the correct options, this is your problem.
    • Fix: Ensure you have babel-loader installed (npm install --save-dev babel-loader @babel/core @babel/preset-react) and a rule in your webpack.config.js like this:
      module.exports = {
        // ... other webpack config
        module: {
          rules: [
            {
              test: /\.(js|jsx)$/,
              exclude: /node_modules/,
              use: {
                loader: 'babel-loader',
                options: {
                  presets: ['@babel/preset-react']
                }
              }
            }
          ]
        }
        // ...
      };
      
    • Why it works: babel-loader tells Webpack to pass all .js and .jsx files through Babel for transpilation. The @babel/preset-react configuration specifically enables the transformation of JSX syntax into React.createElement() calls.
  2. Incorrect File Extension or exclude Rule:

    • Diagnosis: If you’re using .jsx files for your React components, but your Webpack rule only targets .js files, or if node_modules is incorrectly excluded for files that should be transpiled, Babel won’t run on your JSX.
    • Fix: Adjust your Webpack rule’s test property to include .jsx and ensure your exclude rule doesn’t inadvertently block necessary files. A common mistake is excluding everything under node_modules when you might have a specific library that does need transpilation (though this is rare for JSX itself). For your own code, the exclude: /node_modules/ is usually correct.
      // In webpack.config.js
      {
        test: /\.(js|jsx)$/, // Ensure both .js and .jsx are covered
        exclude: /node_modules/,
        use: ['babel-loader']
      }
      
    • Why it works: Explicitly including .jsx in the test regex ensures that files with this extension are processed by the babel-loader.
  3. Missing or Incorrect .babelrc / babel.config.js:

    • Diagnosis: Babel often relies on a configuration file (.babelrc, .babelrc.js, or babel.config.js) for its presets and plugins. If this file is missing, or if it doesn’t include @babel/preset-react, Babel won’t know how to handle JSX.
    • Fix: Create a .babelrc file in your project’s root directory with the following content:
      {
        "presets": ["@babel/preset-react"]
      }
      
      If you’re using babel.config.js (recommended for monorepos or more complex configurations), it would look like:
      module.exports = {
        presets: ['@babel/preset-react']
      };
      
    • Why it works: This file directly instructs Babel to use the React preset, which contains the necessary transformations for JSX.
  4. Using a Custom Babel Preset/Plugin That Conflicts or is Missing:

    • Diagnosis: If you’ve customized your Babel configuration beyond the basic React preset (e.g., using @babel/preset-env or other plugins), there might be a conflict or a missing dependency. Check your package.json for Babel-related dependencies and your Babel config file.
    • Fix: Ensure all necessary Babel packages are installed (npm install --save-dev @babel/core @babel/preset-react @babel/preset-env) and that your .babelrc or babel.config.js correctly lists them. For example, a common setup includes both React and environment presets:
      {
        "presets": [
          "@babel/preset-env",
          "@babel/preset-react"
        ]
      }
      
    • Why it works: @babel/preset-env handles modern JavaScript features, while @babel/preset-react specifically handles JSX. Both are often needed for a complete React build.
  5. Incorrectly Configured TypeScript with jsx Option:

    • Diagnosis: If you’re using TypeScript (.ts or .tsx files) and ts-loader or babel-loader with @babel/preset-typescript, the tsconfig.json file might not be configured to handle JSX properly.
    • Fix: In your tsconfig.json, ensure the jsx compiler option is set to react, react-jsx, or react-jsxdev. For example:
      {
        "compilerOptions": {
          // ... other options
          "jsx": "react-jsx", // or "react" or "react-jsxdev"
          // ...
        }
      }
      
      And your Webpack rule might look like:
      {
        test: /\.(ts|tsx)$/,
        exclude: /node_modules/,
        use: [
          {
            loader: 'babel-loader',
            options: {
              presets: [
                '@babel/preset-env',
                '@babel/preset-react',
                '@babel/preset-typescript'
              ]
            }
          }
        ]
      }
      
    • Why it works: The jsx option in tsconfig.json tells the TypeScript compiler how to process JSX syntax within .tsx files, and the Babel preset ensures that this processing is integrated into the build pipeline.
  6. Caching Issues with Babel/Webpack:

    • Diagnosis: Sometimes, build tools cache configurations or transpiled code, leading to stale results even after you’ve made changes.
    • Fix: Clear your build cache. For Webpack, this often involves deleting the .cache directory (if you’re using Webpack 5’s filesystem cache) or running npm cache clean --force followed by deleting node_modules and running npm install. You can also try restarting your development server (npm start or yarn start).
    • Why it works: This forces the build tools to re-evaluate all files and configurations from scratch, discarding any old, incorrect states.

The next error you’ll likely encounter if you fix this is a "Module not found" error if a component or file is genuinely missing, or a different syntax error if there’s another issue in your code.

Want structured learning?

Take the full React course →