react must be in scope when using jsx
React’s “‘React’ must be in scope when using JSX” error is a classic React/ESLint issue that mostly depends on your React version and tooling configuration.
React Must Be in Scope When Using JSX – Quick Scoop
What the error actually means
When you write JSX like:
jsx
const App = () => <h1>Hello</h1>;
your build setup transforms it to something like:
js
const App = () => React.createElement('h1', null, 'Hello');
So in older setups, React needs to exist in the file, or the transformed
code cannot call React.createElement, and ESLint warns: 'React' must be in
scope when using JSX.
Why this happens (by React version)
Before React 17 (classic JSX runtime)
- JSX compiled directly to
React.createElement(...)calls.
-
Every file using JSX had to import React at the top, for example:
jsx
import React from 'react';
const Button = () => ;
export default Button;
-
If you forgot this import, linters and compilers complained with that exact error.
React 17+ (automatic JSX runtime)
- React 17 introduced an “automatic” JSX runtime where JSX compiles to helper functions from a JSX runtime package, not directly to
React.createElement.
- In that mode, you usually don’t need
import React from 'react';in every component file anymore. The tooling injects the right imports automatically.
But :
- Many ESLint configs and older tutorials still assume the old behavior, so they keep the rule that warns if React is not in scope (
react/react-in-jsx-scope).
- That’s why you can have a working app that still shows this as an ESLint error or red underline in your editor.
Common ways to fix it
1. Add the React import (works everywhere)
For older projects (React 16, early 17, or classic runtime), or when you just want the simplest fix, import React:
jsx
import React from 'react';
const App = () => {
return <h1>Hello, World!</h1>;
};
export default App;
Adding this at the top of any JSX file solves the scope issue in classic setups.
Use this approach if:
- You aren’t sure what JSX runtime you’re using.
- You want a quick, universally safe fix.
- You’re maintaining older code that already imports React everywhere.
2. Turn off the ESLint rule for modern setups
If your project uses the automatic JSX runtime (typical for recent CRA, Vite,
Next.js, etc. with React 17+), you can safely disable react/react-in-jsx- scope because React really doesn’t need to be imported manually.
Example .eslintrc rule:
json
{
"rules": {
"react/react-in-jsx-scope": "off"
}
}
A Reddit discussion confirms this is safe as long as your Babel/TypeScript
config uses the JSX automatic runtime (for example runtime: "automatic" in
@babel/preset-react).
Use this approach if:
- You know your bundler is using the automatic JSX runtime.
- Your code runs fine without importing React, and only ESLint is complaining.
- You prefer cleaner files without a React import at the top just for JSX.
3. Check your tooling (Babel, TypeScript, ESLint)
Sometimes the error is a symptom of a mismatch:
- React version is 17+ but Babel is configured for the classic runtime.
- ESLint plugins are older and expect manual imports.
- TypeScript JSX settings are not aligned with your React JSX transform.
Key things to verify:
- React version :
- Pre‑17 → manual
import Reactrequired. - 17+ → can use automatic runtime if configured.
- Pre‑17 → manual
- Babel config (
@babel/preset-react):- Automatic runtime:
runtime: "automatic"(no import needed). - Classic runtime:
runtime: "classic"(React import needed).
- Automatic runtime:
- ESLint config :
- If using automatic runtime, disable
react/react-in-jsx-scope.
- If using automatic runtime, disable
- TypeScript (
tsconfig.json):- For React 17+ automatic runtime, use
"jsx": "react-jsx"or"react-jsxdev". - For classic runtime,
"jsx": "react"and keepimport React.
- For React 17+ automatic runtime, use
Quick decision guide (what should you do?)
You can think of it like a short choose‑your‑own‑path:
- Does your app build and run, but your editor shows a React-in-scope error?
- Yes → Turn off the ESLint rule
react/react-in-jsx-scopeif you’re on React 17+ with automatic runtime.
- Yes → Turn off the ESLint rule
* No → Go to step 2.
- Check React version:
- React 16 or below
- Always import React in any JSX file.
- React 17+
- If your config uses automatic runtime → disable the ESLint rule.
- If it uses classic runtime → still import React manually or adjust the runtime.
- React 16 or below
- In doubt & under time pressure
- Add
import React from 'react';at the top of the file. - Later, clean up configuration and remove imports if you switch fully to the automatic runtime.
- Add
Forum-style recap (as if you saw this on a dev board)
“I keep getting
./src/App.js Line 2: 'React' must be in scope when using JSX react/react-in-jsx-scopeeven though my app works fine.”
Typical replies:
- “If you’re on a recent React with the automatic JSX runtime, just disable
react/react-in-jsx-scopein your ESLint config.”
- “On older React or classic runtime you still need
import React from 'react';at the top of every JSX file.”
- “Check your Babel preset—if it’s
runtime: 'automatic', the lint rule is obsolete.”
TL;DR bottom
- The error appears because JSX used to compile to
React.createElement, soReacthad to be in scope.
- On older React / classic runtime : add
import React from 'react';in every JSX file.
- On React 17+ with automatic runtime : you usually don’t need to import React; instead, turn off
react/react-in-jsx-scopein ESLint.
- If things feel inconsistent, align React, Babel, TypeScript, and ESLint configs to the same JSX runtime style.
Information gathered from public forums or data available on the internet and portrayed here.