{"record":{"id":"6c8ebc89fcb55f10","repo":"facebook/react","slug":"your-app-or-one-of-its-dependencies-is-using-an","errorCode":null,"errorMessage":"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","messagePattern":"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","errorType":"console","errorClass":null,"httpStatus":null,"severity":"warning","filePath":"packages/react/src/jsx/ReactJSXElement.js","lineNumber":648,"sourceCode":"  // Reserved names are extracted\n  const props = {};\n\n  let key = null;\n\n  if (config != null) {\n    if (__DEV__) {\n      if (\n        !didWarnAboutOldJSXRuntime &&\n        '__self' in config &&\n        // Do not assume this is the result of an oudated JSX transform if key\n        // is present, because the modern JSX transform sometimes outputs\n        // createElement to preserve precedence between a static key and a\n        // spread key. To avoid false positive warnings, we never warn if\n        // there's a key.\n        !('key' in config)\n      ) {\n        didWarnAboutOldJSXRuntime = true;\n        console.warn(\n          'Your app (or one of its dependencies) is using an outdated JSX ' +\n            'transform. Update to the modern JSX transform for ' +\n            'faster performance: https://react.dev/link/new-jsx-transform',\n        );\n      }\n    }\n\n    if (hasValidKey(config)) {\n      if (enableOptimisticKey && config.key === REACT_OPTIMISTIC_KEY) {\n        key = REACT_OPTIMISTIC_KEY;\n      } else {\n        if (__DEV__) {\n          checkKeyStringCoercion(config.key);\n        }\n        key = '' + config.key;\n      }\n    }\n","sourceCodeStart":630,"sourceCodeEnd":666,"githubUrl":"https://github.com/facebook/react/blob/eafeac097ba51e1eab809c07102126bd5f8e5425/packages/react/src/jsx/ReactJSXElement.js#L630-L666","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before: tsconfig.json\n{ \"compilerOptions\": { \"jsx\": \"react\" } }\n\n// after\n{ \"compilerOptions\": { \"jsx\": \"react-jsx\" } }","handlingStrategy":"validation","validationCode":"// scripts/check-jsx-transform.mjs - fail CI if classic-transform output ships\nimport {readFileSync, existsSync} from 'node:fs';\n\nfor (const file of ['dist/bundle.js']) {\n  if (!existsSync(file)) continue;\n  const code = readFileSync(file, 'utf8');\n  if (code.includes('__self:') || /,\\s*__self\\s*=/.test(code)) {\n    throw new Error(\n      `${file}: classic JSX transform detected - build with the automatic runtime`,\n    );\n  }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["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"],"tags":["jsx-transform","babel","createelement","build-config","migration","dev-only"],"backgroundTag":"legacy-jsx-transform","analyzedSha":"eafeac097ba51e1eab809c07102126bd5f8e5425","analyzedAt":"2026-08-21T22:01:08.818Z","schemaVersion":2},"datasetVersion":"2026-08-21T23:17:16.201Z"}