React 19.3 View Transitions: A Practical Guide
React 19.3 stabilizes ViewTransition. Learn to animate UI changes with a working example, understand when animations run, and respect reduced-motion preferences.
React 19.3, released in September 2026, made ViewTransition a stable React component. It helps animate specific UI changes such as showing a card, updating a panel, or switching between views. This guide builds a small example and explains the conditions required for the animation to run.
This example requires React 19.3 or later. Check the installed versions of react and react-dom before trying it in an existing project.
What does ViewTransition do?
ViewTransition defines an animation boundary around part of your component tree. When an update is marked as a Transition, React coordinates the before and after views using the browser's View Transition API. The default behavior is typically a smooth cross-fade.
React recognizes four kinds of change: enter, exit, update, and share. You can start with the default effect and add custom styles later.
A practical Editor and Preview panel example
Place this code in App.jsx in a React 19.3 or newer project:
import { startTransition, useState, ViewTransition } from "react";
import "./App.css";
const panels = [
{
title: "Editor",
description: "Write your components and refine the code.",
},
{
title: "Preview",
description: "See what your interface looks like as you build.",
},
];
export default function App() {
const [active, setActive] = useState(0);
function selectPanel(index) {
startTransition(() => {
setActive(index);
});
}
return (
<main className="demo">
<div className="switcher" aria-label="Choose a panel">
{panels.map((panel, index) => (
<button
key={panel.title}
type="button"
aria-pressed={active === index}
onClick={() => selectPanel(index)}
>
{panel.title}
</button>
))}
</div>
<ViewTransition>
<article className="panel">
<h2>{panels[active].title}</h2>
<p>{panels[active].description}</p>
</article>
</ViewTransition>
</main>
);
}
Add the styles to App.css:
.demo {
max-width: 640px;
margin: 4rem auto;
padding: 1rem;
font-family: system-ui, sans-serif;
}
.switcher {
display: flex;
gap: 0.75rem;
margin-bottom: 1.5rem;
}
.switcher button {
padding: 0.7rem 1rem;
border: 1px solid #79cdb6;
border-radius: 0.75rem;
background: #fff;
cursor: pointer;
}
.switcher button[aria-pressed="true"] {
background: #0f766e;
color: #fff;
}
.panel {
min-height: 120px;
padding: 1.5rem;
border: 1px solid #cbd5e1;
border-radius: 1rem;
background: #f8fafc;
}
@media (prefers-reduced-motion: reduce) {
::view-transition-old(*),
::view-transition-new(*) {
animation-duration: 0.01ms !important;
}
}
Clicking either button updates state inside startTransition. ViewTransition surrounds the panel, so React can animate the change to its contents. The buttons use aria-pressed to expose the selected state to assistive technology.
Why does startTransition matter?
Wrapping a component in ViewTransition does not animate every state update. Ordinary updates intended to appear immediately do not activate it. In this example, startTransition marks the panel switch as a Transition. Suspense reveals and updates caused by useDeferredValue can also trigger a View Transition.
Do not wrap every interaction in startTransition for the sake of animation. A controlled text input, for example, needs an immediate response while someone types.
Three practical guidelines
- Keep the boundary focused. Wrapping an entire page can animate changes you did not intend to animate. Put ViewTransition around the card, panel, or route section that needs it.
- Respect reduced-motion preferences. React does not automatically turn the animation off for people who request reduced motion. The CSS above shortens the animation when prefers-reduced-motion is enabled.
- Try the default effect first. If a cross-fade is enough, you do not need custom animation CSS. For more control, React lets you customize enter, exit, update, and share behavior.
If you do not see an animation, check the React version, whether the update runs inside startTransition, browser support for the View Transition API, and the device's reduced-motion setting.
Frequently asked questions
Does ViewTransition replace CSS animations?
No. It helps coordinate snapshots before and after a view change. CSS and other animation tools are still useful for effects inside individual elements or for more detailed motion.
Will every state update animate?
No. An ordinary state update does not activate ViewTransition by itself. In the example, startTransition triggers the animation.
Can I use this example with older React versions?
No. ViewTransition became stable in React 19.3. Check the versions of react and react-dom before using the example.
You can use the Coderilo editor to explore React component structure and preview changes. Running this specific API requires a project runtime with React 19.3 or later.


