Choosing between native transitions, React ViewTransition, Motion and react-morphcard.
View Transitions can implement a card-to-detail transition. Choose react-morphcard for its specific interaction contract: a mounted detail sheet, shared elements, Back that reverses the current flight, scroll restoration and visibility fallbacks. It is not a general replacement for the browser API or an animation framework.
| Requirement | Starting point |
|---|---|
| Navigation between pages or replacement of an entire view | Native View Transitions, or your router's integration |
| React updates coordinated with Suspense and transitions | React <ViewTransition> |
| Reordering layouts, gestures, springs and many kinds of shared elements | Motion layout / layoutId |
| A card opening a mounted sheet, with immediate reversal on Back | react-morphcard |
These are recommendations, not performance rankings. Profile the actual page on target devices before claiming one approach is faster.
Native View Transitions capture the old and new views and animate their pseudo-elements. Starting another document transition skips the active one; it does not automatically reverse its progress. Custom scheduling and animation control can change that behaviour. See the View Transitions specification.
React's <ViewTransition> coordinates capture with React commits. Its documented scheduling finishes the current React transition and batches queued updates into the next one. It also handles shared boundaries outside the viewport by using enter/exit behaviour. You still configure reduced motion. See the React reference.
Do not assume View Transitions always block the whole page or allow only one independent animation. Chrome 147 added element-scoped transitions, including concurrent and nested transitions; the rest of the page can stay interactive. Check support separately from document-level transitions. See Chrome's element-scoped API.
The hook animates the actual sheet and shared elements through WAAPI, plus a temporary copy of the card. It owns a narrow choreography:
open({ key, item }) updates the mounted detail before geometry is measured.That behaviour comes with maintenance cost: DOM measurement, clipping, copies, focus and browser-specific animation details. Native capture avoids maintaining some of that machinery. The published, unminified ESM build measured about 15.4 kB gzipped during the September 2026 review, excluding React; consumer minification and tree shaking change the result.
Motion's layout and layoutId support layout and shared-element animation, with AnimatePresence for exits and options for scroll/fixed layouts. If the app already uses Motion for gestures and springs, build the sheet there before adding another animation dependency. See Motion layout animations.
Use separate ownership boundaries: for example, route navigation through React ViewTransition and card details through react-morphcard. Avoid scheduling both on the same subtree at the same time. In particular, this hook uses flushSync before measurement, which can cause React to skip a pending ViewTransition. Let one interaction finish or skip before starting the other.
The hook is an animation primitive, not a complete modal system. See Accessibility for the surrounding dialog's responsibilities.
Made by Lucas Piera