Below is a list of all new features, APIs, and bug fixes.
Read the React 19.3 release post for more information.
New React Features
<ViewTransition />: Adds<ViewTransition />andaddTransitionTypeAPIs to power View Transition animations in React (@sebmarkbage, @jackpope, @gaearon: #31975, #31987, #31996, #31999, #32001, #32002, #32028, #32029, #32031, #32034, #32038, #32041, #32050, #32090, #32105, #32254, #32379, #32422, #32462, #32540, #32545, #32585, #32599, #32611, #32612, #32617, #32651, #32653, #32656, #32664, #32699, #32723, #32734, #32751, #32752, #32760, #32761, #32764, #32772, #32790, #32819, #32820, #32822, #32833, #32849, #33094, #33191, #33200, #33206, #33293, #33330, #33331, #33332, #33357, #33362, #33433, #33576, #34374, #34450, #34481, #34500, #34502, #34510, #34511, #34539, #35567, #35564, #35485, #35380, #35063, #35060, #34676, #36917, #35337, #35520)- Fragment Refs: Add Refs to
<Fragment />to support composable platform behavior (@jackpope, @sebmarkbage, @eps1lon, @Dhakshin2007, @chirokas, @teamleaderleo, @fallintoplace: #32465, #32613, #32619, #32654, #32660, #32682, #32722, #32813, #32814, #33056, #33058, #33093, #34069, #34103, #34544, #34545, #37062, #37061, #37060, #36047, #36010, #35642, #35641, #35637, #35630, #34935, #37457, #37408, #37326, #37251, #37171, #37169, #37168, #37167, #37166, #37165, #37164, #37163, #37162, #37161, #37160, #37125, #37063)
New React DOM Features
browser(): a newreact-domAPI that returns a usable which errors during server rendering and resolves in the browser.use(browser())inside a<Suspense>boundary marks a subtree as browser-only without reporting a recoverable error (@gnoff: #37143, #37241)
Notable changes
- Enable Trusted Types API integration (@rickhanlonii #35816)
- Transitions now render independently instead of being entangled into a single render, so a slow transition no longer holds up unrelated ones (@acdlite #37290)
- Added a DEV-only warning when a component appears to have been unblocked by calling
use()conditionally (@hoxyq, @eps1lon: #37104, #37203, #37491)
All Changes
React
- Fast Refresh Fixes
- Fix Fast Refresh to find and remount edits to components wrapped behind
lazy()(@sophiebits #36965) - Fix Fast Refresh so edits to a
memo()comparison function take effect (@sophiebits #36964) - Fix Fast Refresh crash when an edit changes the kind of a component's type (@sophiebits #36963)
- Unify hot reload type resolution for Fast Refresh (@sophiebits #36962)
- Fix Fast Refresh to remount correctly when an edit changes the component kind (@sophiebits #36950)
- Double invoke effects in StrictMode after Fast Refresh (@eps1lon #35962)
- Fix Fast Refresh to find and remount edits to components wrapped behind
- Performance Track Fixes
- Prevent crash when accessing
$$typeofin Performance Tracks (@eps1lon #35679) - Handle non-string function names in Performance Tracks (@eps1lon #35659)
- Use minus (
-) instead of en dash for removed props in Performance Tracks (@eps1lon #35649) - Handle arrays with bigints in deep objects in Performance Tracks (@eps1lon #35648)
- Don't enumerate typed array props in Performance Tracks in DEV (@UditDewan #36913)
- Bail out of diffing wide objects and arrays in Performance Tracks (@eps1lon #34742)
- Clear potentially large performance measures in DEV (@hoxyq #34803)
- Fix missing else branch for renders with no props change in Performance Tracks (@hoxyq #34837)
- Prevent crash when accessing
- Activity Fixes
- Fix
useSyncExternalStoremissing store mutations that happened while an Activity tree was hidden (@sophiebits #36947) - Hide portal contents when an Activity is hidden (@acdlite #35091)
- Prevent metadata hoisting in hidden
<Activity>trees (@ronnakamoto #34983) - Prevent errors thrown inside a hidden Activity from escaping to the visible UI (@acdlite #35074)
- Don't unhide a node if a direct parent Offscreen is still hidden (@sebmarkbage #34821)
- Don't show internal
<Offscreen>component in error messages (@rickhanlonii #35763)
- Fix
- Warn in DEV when a component appears to have been unblocked by a conditional
use()(@hoxyq, @eps1lon: #37104, #37203, #37491) - Render transitions independently instead of entangling them into a single render (@acdlite #37290)
- Fix hang when updating a dehydrated boundary inside a hidden tree (@gaearon #37135)
- Don't reacquire Host Singletons during dev effect validation (@gnoff #37113)
- Only remove properties from Host Singletons on release (@gnoff #37112)
- Don't invoke effects on moved children in StrictMode (@sophiebits #36948)
- Throw a clearer error when a rejected Promise is incorrectly instrumented (@eps1lon #36328)
- Fix context propagation into Suspense fallbacks (@acdlite #36160)
- Fix context propagation through suspended Suspense boundaries (@acdlite #35839)
- Fix
useDeferredValuegetting stuck (@gaearon #36134) - Update
useActionStateerror message to say "action state" instead of "form state" (@rickhanlonii #35790) - Don't warn when rendering data block scripts (@eps1lon #35953)
- Treat fibers with alternates as mounted in
getNearestMountedFiber(@sebmarkbage #35578) - Always instrument the lazy initializer thenable (@gnoff #35521)
- Annotate cascading updates for DevTools performance tracks in DEV (@huntie #34961)
- Resolve the
.defaultexport of aReact.lazyas the canonical value (@sebmarkbage #34906) - Limit owner stacks to 10 frames (@eps1lon #34864)
- Ensure
useEffectEventreads latest values inforwardRefandmemo()components (@eps1lon #34831)
React DOM
- Copy
sourceonto the synthetictoggleevent (@lazerg #37389) - Update HTML parser rules for the new
<select>parser (@josepharhar #34804) - Update
defaultValuefortype="number"inputs to match other input types (@sophiebits #36980) - Avoid setting
innerHTMLwhen it hasn't changed (@sophiebits #36949) - Forward the
nonceoption inReactDOM.preloadModule()(@UditDewan #36851) - Support
fetchPriorityfor module resources (@TheAlexLichter #36835) - Track stylesheet preloads when explicitly preloaded to avoid unnecessary suspension (@gnoff #36386)
- Suggest correct casing for the misspelled
credentiallessiframe attribute (@vmx906 #36322) - Add
credentiallessas a recognized boolean attribute for iframes (@vmx906 #36148) - Prevent reentrant
finishedTaskfrom callingcompleteAllmultiple times (@gnoff #36287) - Update the CSS shorthand property list (@kidonng #35636)
- Support the
maskTypeSVG prop (@sleitor #35921) - Add support for
onFullscreenChangeandonFullscreenErrorevents (@chirokas #34621) - Include
submitterinsubmitevents (@eps1lon #35590) - Fire
onResetwhen automatically resetting forms (@eps1lon #35176) - Use the
FormDatasubmitterparameter (@jenseng #29028) - Fix form status reset when component state is updated (@eps1lon #34075)
- Batch updates from
resizeevents until the next frame (@eps1lon #35117)
React Server
- Add
nonceto rendered import maps (@mattcosta7 #37339) - Add an
onBrowserBailoutoption to observe subtrees that defer to the browser (@gnoff #37193) - Stop the caller's signal from retaining a finished render (@unstubbable #37315)
- Construct the render lifetime controller only when it is needed (@unstubbable #37357)
- Fix
react-dom/serverhanging on Deno (@fraidev #35235) - Extend stack overflow recovery to retries in SSR (@jackpope #36977)
- Fix false-positive hydration mismatch on
nonceattributes (@MaxwellCohen #37030) - Guard shell-error callbacks instead of nulling them out on the request (@eps1lon #36916)
- Stop firing
onAllReadyafter the shell errored (@eps1lon #36903) - Treat an incomplete tree as an error during error recovery (@acdlite #36911)
- Fix non-script
modulepreloadtracking (@fallintoplace #36564) - Finalize postponed
nextSegmentIdafter the prelude flush (@gaojude #36779) - Preserve
referrerPolicyin image preload headers (@ulises-jeremias #36803) - Allow pending work to specialize abort reasons (@gnoff #36586)
- Abort tasks that suspend after aborting during render (@gnoff #36585)
- Finish abort in a scheduled task (@gnoff #36580)
- Fix aborts during resumed rendering (@gnoff #36584)
- Track abort state on the request (@gnoff #36583)
- Model external work scheduling explicitly in the fb bundle (@gnoff #36576)
- Continue reporting aborted task errors after a fatal abort (@gnoff #36575)
- Disallow abort reentrancy (@gnoff #36574)
- Stop transpiling computed property names (@eps1lon #36542)
- Fix crash when capturing the callsite of a stalled
use()of a rejected Flight chunk (@lubieowoce #36544) - Double invoke effects in Strict Mode during hydration (@eps1lon #35961)
- Add additional task reentrancy protections in Fizz (@gnoff #36291)
- Don't outline Suspense boundaries with suspensey CSS during shell flush (@gnoff #35824)
- Push a stalled
use()to the owner stack and debug task (@eps1lon #35226) - Fix
useIdtracking on replay (@gnoff #35518) - Correctly handle replaying when hydrating (@gnoff #35494)
- Simplify the
createSuspenseBoundarypath (@sebmarkbage #35087) - Unify preamble-only fields to save a field on Suspense boundaries (@sebmarkbage #35068)
- Unify prerender-only fields to save a field on Suspense boundaries (@sebmarkbage #35067)
- Push halted awaits to the owner stack for late-arriving I/O info (@unstubbable #35019)
- Include all Node.js APIs in the Bun entrypoint for
react-dom/server(@RiskyMH #34193) - Detach a Suspense boundary after flushing its segment (@gnoff #34694)
React Server Components
- Keep an element pending while a referenced row is resolving (@unstubbable #37542)
- Fix
RangeErrorfrom exponential debug info growth (@unstubbable #37481) - Abort the cache signal when debug objects are retained (@unstubbable #37342)
- Transfer key validation of lazy nodes when they are unwrapped (@unstubbable #37258)
- Add
pending_weakto the Flight thenable protocol (@acdlite #37154) - Outline and dedupe repeated strings (@gaearon #37147)
- Port Reply Server traversal guards to the Flight Client (@eps1lon #37144)
- Define Flight chunk
.thenwithObject.defineProperty(@eps1lon #37109) - Support Turbopack's experimental array format for chunks (@sampoder #37095)
- Limit fake JSX call site stacks to 10 frames (@timneutkens #37086)
- Improve performance when decoding Flight replies (@gnoff #37090)
- Recognize Node 22+ V8 frames for
Promisestatics in debug info (@gaearon #36969) - Tailor the warning for binary data serialized through
toJSON(NodeBuffer) (@unstubbable #36873) - Resolve models before
JSON.stringifyfor faster serialization (@mhart #36795) - Prune debug info when chunks error (@gnoff #36782)
- Avoid main-thread stalls from large debug strings (@unstubbable #36570)
- Fix stranded row content under Node stream backpressure (@unstubbable #36516)
- Fix dropped
FormDataentries indecodeReplyFromBusboy(@unstubbable #36468) - Harden types and improve performance of Flight replies (@eps1lon #36425)
- Add more cycle protections to Flight replies (@eps1lon #36236)
- Transport
AggregateError.errors(@eps1lon #36156) - Bail out early when a backing entry for
Blobdeserialization is not aBlob(@eps1lon #36055) - Clear chunk reason after successful module initialization (@unstubbable #36024)
- Add support for transporting
Error.cause(@eps1lon #35810) - Walk parsed JSON instead of using a reviver for faster RSC payload parsing (@timneutkens #35776)
- Skip
transferReferencedDebugInfoduring debug info resolution (@unstubbable #35795) - Add
unstable_allowPartialStreamoption to Flight Client (@unstubbable #35731) - Fix
encodeReplyfor JSX with temporary references (@unstubbable #35730) - Fix debug channel flag in Node.js
renderToPipeableStream(@feedthejim #35724) - Fix stack overflow in
visitAsyncNodewith deep async chains (@unstubbable #35612) - Allow Server Components to render context providers from client modules (@rickhanlonii #35675)
- Allow overriding
request.timeOriginviaoptions.startTime(@lubieowoce #35598) - Warn once if
evalis disabled in the dev environment (@eps1lon #35661) - Restore original function name in dev server callstacks served with
unsafe-eval(@eps1lon #35650) - Fix
react-markuptypes for server references (@eps1lon #35634) - Add more DoS mitigations to Flight replies and harden Flight (@unstubbable #35632)
- Allow cyclic references to be serialized when unwrapping lazy elements (@unstubbable #35471)
- Improve cyclic thenable detection in Flight reply server (@cvan20191 #35369)
- Add extra loop protection to Flight reply server (@sebmarkbage #35351)
- Patch Promise cycles and
toStringon Server Functions (@sebmarkbage #35345) - Move
react-server-dom-webpack/*.unbundledto privatereact-server-dom-unbundled(@eps1lon #35290) - Never parse
thenfunctions in Flight replies (@sebmarkbage #35289) - Patch Flight reply server with fixes from Flight Client (@sebmarkbage #35277)
- Complete the list of Node.js internal Promise awaits (@eps1lon #35161)
- Reduce risk of maximum call stack exceeded when emitting async sequences (@eps1lon #35159)
- Fix pending chunks count for streams and async iterables in DEV (@unstubbable #35143)
- Fix broken byte stream parsing caused by buffer detachment (@unstubbable #35127)
- Fix
hasReadableflag in Node.js clients' debug channel (@unstubbable #35039) - Fix debug info filtering to include later resolved I/O (@unstubbable #35036)
- Cache the value when visiting the same I/O or Promise along different paths (@sebmarkbage #35005)
- Clone subsequent I/O nodes when resolved more than once (@sebmarkbage #35003)
- Fix hang after resolving cyclic references (@unstubbable #34988)
- Allow passing DEV-only
startTimeas an option (@sebmarkbage #34912) - Ignore bound-anonymous-fn resources as they're not considered I/O (@sebmarkbage #34911)
- Fix detached
ArrayBuffererror when streaming typed arrays (@unstubbable #34849) - Exclude RSC stream if the stream resolves in a task (@sebmarkbage #34838)
- Forward the current environment when forwarding I/O entries (@sebmarkbage #34836)
- Look for moved debug info when logging component performance track (@sebmarkbage #34839)
- Respect
displayNameof Promise instances on the server (@sebmarkbage #34825) - Avoid unnecessary indirection when serializing debug info (@unstubbable #34797)
- Fix preload
asattribute for stylesheets (@unstubbable #34760) - Don't serialize
toJSONin debug path and omit wide arrays (@sebmarkbage #34759) - Add support for
<Activity>(@eps1lon #34697)