facebook/react · warning
Your app (or one of its dependencies) is using an outdated J
Error message
Your app (or one of its dependencies) is using an outdated JSX transform. Update to the modern JSX transform for faster performance: https://react.dev/link/new-jsx-transform
What it means
In dev, createElement checks whether its config object contains __self but no key (ReactJSXElement.js:648). __self/__source are injected by the classic JSX transform's Babel development plugins; the modern automatic transform emits jsx(...) calls that never set __self, and the rare automatic-transform fallback to createElement always includes a key - which is why 'key' in config suppresses the check. Seeing __self therefore means some module in the bundle was compiled with the pre-React-17 classic transform.
Source
Thrown at packages/react/src/jsx/ReactJSXElement.js:648
// Reserved names are extracted
const props = {};
let key = null;
if (config != null) {
if (__DEV__) {
if (
!didWarnAboutOldJSXRuntime &&
'__self' in config &&
// Do not assume this is the result of an oudated JSX transform if key
// is present, because the modern JSX transform sometimes outputs
// createElement to preserve precedence between a static key and a
// spread key. To avoid false positive warnings, we never warn if
// there's a key.
!('key' in config)
) {
didWarnAboutOldJSXRuntime = true;
console.warn(
'Your app (or one of its dependencies) is using an outdated JSX ' +
'transform. Update to the modern JSX transform for ' +
'faster performance: https://react.dev/link/new-jsx-transform',
);
}
}
if (hasValidKey(config)) {
if (enableOptimisticKey && config.key === REACT_OPTIMISTIC_KEY) {
key = REACT_OPTIMISTIC_KEY;
} else {
if (__DEV__) {
checkKeyStringCoercion(config.key);
}
key = '' + config.key;
}
}
View on GitHub (pinned to eafeac097b)
Solutions
- Switch the app compiler to the automatic runtime: Babel preset-react {runtime:'automatic'}, TypeScript jsx:'react-jsx', esbuild --jsx=automatic, SWC runtime:'automatic'
- Identify the offending module in dev (the component/stack near the warning) and update or rebuild that dependency with the automatic transform
- Report to the package maintainer if a dependency ships classic-transformed code - it should publish untransformed JSX or use the automatic runtime
Example fix
// before: tsconfig.json
{ "compilerOptions": { "jsx": "react" } }
// after
{ "compilerOptions": { "jsx": "react-jsx" } } Defensive patterns
Strategy: validation
Validate before calling
// scripts/check-jsx-transform.mjs - fail CI if classic-transform output ships
import {readFileSync, existsSync} from 'node:fs';
for (const file of ['dist/bundle.js']) {
if (!existsSync(file)) continue;
const code = readFileSync(file, 'utf8');
if (code.includes('__self:') || /,\s*__self\s*=/.test(code)) {
throw new Error(
`${file}: classic JSX transform detected - build with the automatic runtime`,
);
}
} Prevention
- Set jsx:'react-jsx' (TS), runtime:'automatic' (Babel), --jsx=automatic (esbuild)
- Prefer dependencies that ship untransformed JSX or automatic-runtime output
- Re-check compiler config after major React upgrades
- Remember the warning never fires when key is present, so key-carrying createElement calls are fine
When it happens
Trigger: Any dependency or app module compiled with @babel/preset-react without runtime:'automatic' (or tsconfig jsx:'react', esbuild --jsx=transform, classic SWC settings) running in development mode, so Babel injects __self into the createElement config.
Common situations: Upgrading React 16 to 17+/18/19 without touching compiler settings; node_modules packages shipping unminified classic-transform output; custom esbuild/SWC pipelines still configured for classic JSX.
Related errors
- 414
- React Refresh Babel transform should only be enabled in deve
- Failed to parse source file: ${originalSourceURL} Original
- 320
- 509
AI-assisted analysis of facebook/react@eafeac097b (2026-08-21).
Data as JSON: /api/errors/6c8ebc89fcb55f10.
Report an issue: GitHub.