PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteReact 19.3 makes <ViewTransition> stable. Wrap part of your rendered tree in it, and React coordinates that part with the browser’s View Transition API when the content enters, exits, changes, or moves to another location under a shared name. The default effect is a cross-fade. Animation only happens when the update is one React treats as a Transition, so an ordinary urgent state change still renders immediately with no motion. The feature is built for page-level and UI-level transitions, not for every animation in an interface.
Where the feature stands
The React Team announced React 19.3 on September 9, 2026, and stated that both ViewTransition and Fragment Refs, which were previously experimental, are now stable (React 19.3 release announcement). The stable status is limited to the DOM. The announcement says: “Currently, <ViewTransition> only works in the DOM.” React Native and other platforms are still in development, so the component should not be assumed to work in non-browser React renderers.
As an Amazon Associate I earn from qualifying purchases.
The feature has a longer history. On April 23, 2025, Ricky Hanlon’s React Labs article described View Transitions as experimental and available for testing (React Labs: View Transitions, Activity, and more). The 2026 release is the point at which that experimental status ended.
Two separate opt-ins: the boundary and the trigger
An animation needs two decisions, and confusing them is the most common reason an update fails to move.
#1 Best Overall
- The boundary decides what may animate. Wrapping markup in
<ViewTransition>makes that subtree eligible for coordination. Markup outside the boundary is not animated by that component. - The trigger decides when. The update must come from a supported source: a state update inside
startTransition, a Suspense reveal, or an update that flows throughuseDeferredValue. The React 19.3 announcement lists these as the animation triggers.
The four kinds of change React can animate
React classifies what happened inside a boundary into four cases. The classification determines which visual transition the browser runs.
| Change | What happened in the tree | Example |
|---|---|---|
| Enter | A <ViewTransition> boundary is added |
A details panel mounts after a toggle |
| Exit | A boundary is removed | The same panel unmounts |
| Update | The boundary stays, and its children change style or content | A card changes its label or layout in place |
| Share | A named boundary disappears in one place and appears in another with the same name | A thumbnail in a list becomes the image on a detail page |
The share case is the one that produces the most visible motion. The React Labs article uses a thumbnail with a consistent name across a list view and a detail view, with the route change wrapped in <ViewTransition>. It also shows transition types selecting different classes for forward and back navigation, so the same route change can look different depending on direction.
A minimal example that animates
This sketch uses only the component and startTransition. Because the state change runs inside startTransition, the conditional content’s appearance and disappearance are eligible for the animation.
import { ViewTransition, startTransition, useState } from 'react';
function Details() {
const [open, setOpen] = useState(false);
return (
<>
<button onClick={() => startTransition(() => setOpen(o => !o))}>
{open ? 'Hide' : 'Show'} details
</button>
<ViewTransition>
{open && <p>Extra content that fades in and out.</p>}
</ViewTransition>
</>
);
}
For the full list of props and edge cases, check the ViewTransition reference on react.dev before shipping production code, since this sketch does not depend on any prop.
Rank #3
Customizing the motion
The default is a cross-fade. To change it, style the browser’s View Transition pseudo-elements with CSS and attach View Transition class names, or use Web Animations API callbacks for finer control over timing and keyframes. Because browser support for the underlying View Transition API varies, confirm current browser compatibility before relying on a specific effect.
ViewTransition or a CSS animation?
The React Labs article states: “View Transitions are meant to be used for UI transitions such as navigation, expanding, opening, or re-ordering.” Effects on a single element, such as a like-button pulse or a loading glimmer, remain better suited to CSS or JavaScript animation.
Rank #4
| Question | ViewTransition | CSS or JavaScript animation |
|---|---|---|
| Scope | Page or UI-level changes such as navigation, expanding, opening, or reordering | Individual elements, such as a button effect or a loading indicator |
| Trigger | Transition-marked state updates, Suspense reveals, or deferred values | Whenever you choose to run it, including urgent updates |
| Control | Browser snapshot-style transition, customized with View Transition classes or Web Animations API callbacks | Direct styling and timing of the element |
| Platform | DOM only in React 19.3 | Depends on your stack |
| Loading behavior | A Suspense reveal wrapped in the component can wait up to 500 ms for fonts and visible images | Not coordinated by React |
Why an update doesn’t animate
When a change appears with no motion, check these causes in order.
The update is urgent
An unmarked state update is treated as urgent and rendered immediately. In the example above, removing the startTransition wrapper turns the toggle into an urgent update, and the panel appears or disappears without the animation. Wrap the state change in startTransition to make it eligible.
Best Value
The state change happens after an await
According to the useTransition reference, startTransition marks the updates scheduled during its callback. It does not delay running the callback itself. State updates that happen after an await inside an async action need their own startTransition wrapper; a wrapper around the original call does not carry over.
The changing markup sits outside the boundary
The boundary defines what can animate. If the element that changes is not inside a <ViewTransition>, React has nothing to coordinate for it, so move the boundary to enclose the changing content.
The effect is a small element animation
If you want a single element to pulse or shimmer, a CSS or JavaScript animation is the right tool. Wrapping that element in a boundary is not the intended use.
The app renders outside the DOM
Because the stable component works only in the DOM, a React Native or other non-DOM renderer will not produce these transitions in React 19.3.
Suspense reveals and asset loading
When a Suspense reveal is wrapped in <ViewTransition>, React waits up to 500 ms for new fonts and visible images before starting the animation, according to the Suspense reference. This is a bounded wait, not a guarantee that every asset has loaded when the motion begins. An image with loading="lazy" or an onLoad handler opts out of that image wait. Suspense reveals without the wrapper do not get this behavior.
Quick Recap
“
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.




