View Transitions

<ViewTransition> animates a subtree as it enters, leaves, moves or changes, driving the browser's View Transition API from React 7,897 's own scheduler. It became a stable export of react in React 19.3, released 9 September 2026, after eighteen months in the experimental channel. Wrapping a subtree is enough for the browser's default cross-fade; the enter, exit, update and share props take View Transition Classes, styled with ::view-transition-new(.class) rules.

One point connects this to the rest of the section: a plain setState never activates a view transition. Only an update inside a Transition, a Suspense reveal, or a change flowing through useDeferredValue does — the updates React can hold back until the animation is ready.

A slideshow that animates in the direction you movedJavaScript
import { ViewTransition, addTransitionType, startTransition, useState } from 'react';
export default function Slideshow({ slides }) {
  const [i, setI] = useState(0);
  const go = (step, type) => startTransition(() => {
    addTransitionType(type);                    // 'next' or 'previous'
    setI((n) => (n + step + slides.length) % slides.length);
  });
  return <>
    <button onClick={() => go(-1, 'previous')}>Prev</button>
    <button onClick={() => go(1, 'next')}>Next</button>
    <ViewTransition key={i} enter={{ next: 'from-right', previous: 'from-left' }}
                    exit={{ next: 'to-left', previous: 'to-right' }}>
      <img src={slides[i]} alt="" />
    </ViewTransition>
  </>;
}

addTransitionType tags the update so one boundary animates differently depending on what caused it — forward and back navigation being the standard case. A <ViewTransition> must sit outside the DOM node it animates, or React cannot attach enter and exit animations. Give a name only to a shared element moving between two places, and mount one element with that name at a time.