Add React 19.3 adoption codemods and recipe - #8
Merged
Merged
Conversation
Add three JSSG codemods for the APIs that stabilized in React 19.3 (plus the 19.2 leftovers), and a recipe that chains them: - react-19-3-unprefix-stable-apis: rename unstable_ViewTransition, unstable_addTransitionType, unstable_Activity and experimental_useEffectEvent to their stable names across ESM and CJS imports, member access, JSX tags, re-exports and usage sites. - react-19-3-use-browser: replace the useState(false) + useEffect mounted-state pattern with use(browser()) from react-dom, splitting the component so the old early return becomes a Suspense fallback. - react-19-3-fragment-ref-wrappers: replace display:contents wrapper elements that only hold a ref with <Fragment ref>, guarded by a check that every ref usage is on the FragmentInstance API. - react-19-3-migration-recipe: runs the above together with react-19-remove-context-provider. Also add the lockfile importer entries for the new workspace packages and list the codemods in the root README. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1zn9AbvKVCERf15x3zJ68
The JSSG test runner compares metrics.json byte for byte and the existing fixtures have no trailing newline. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01C1zn9AbvKVCERf15x3zJ68
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
React 19.3 (release post) has no breaking changes, so these are adoption codemods: they move code from experimental names and pre-19.3 workarounds onto the stable APIs.
New packages under
codemods/:react-19-3-unprefix-stable-apisunstable_ViewTransition,unstable_addTransitionType(19.3),unstable_Activity,experimental_useEffectEvent(19.2) to their stable names. Covers named imports with/without aliases,React.unstable_Xmember access and JSX member tags, CJSrequire("react")destructuring, re-exports, and all usage sites. Keeps the old local name when the stable name is already taken in the file. Leavesunstable_startGestureTransitionalone.react-19-3-use-browseruseState(false)+useEffect(() => setMounted(true), [])+if (!mounted) return <Fallback />idiom intouse(browser())fromreact-dom. The component is split so the old early return becomes a<Suspense fallback>in a wrapper that keeps the original name and export; the inner component callsuse(browser()). Handles function declarations, arrow components (includingFC<Props>annotations), destructured props, namespace hook access (React.useState→React.use/React.Suspense), and cleans up unuseduseState/useEffect/useLayoutEffectimports. Bails when the flag is used elsewhere or the fallback references destructured props.react-19-3-fragment-ref-wrappers<div ref={r} style={{ display: "contents" }}>/<span …>wrappers with<Fragment ref={r}>. Only fires when every use of the ref in the file is its declaration, this wrapper'srefprop, orr.current.<FragmentInstance method>. Adds aFragmentimport (or usesReact.Fragment) as needed, keeping a leading"use client"directive first.react-19-3-migration-recipereact-19-remove-context-provider.Also: lockfile importer entries for the new workspace packages, and root README sections.
Test plan
pnpm run check-typespasses for all packages.Note: the session that authored this could not reach the npm registry, so the fixtures were traced by hand and first executed in CI. The only correction needed was a trailing newline in the
metrics.jsonfixtures.🤖 Generated with Claude Code
https://claude.ai/code/session_01C1zn9AbvKVCERf15x3zJ68