Prebuilt Interaction Patterns vs Hand-Built Animations in React
Choose between native APIs, animation libraries, and reusable source-first patterns based on how much control, orchestration, and project-specific adaptation the interaction actually requires.


Vidushi Saxena
Developer
Category: Engineering
A button that shifts on press, a card that moves between layouts, and a pinned product story with changing media can all be called “React animation.” They are not the same engineering problem.
For simple state feedback, CSS may be enough. React 19.3 gives teams a stable <ViewTransition> component for DOM elements entering, exiting, moving, resizing and transitioning between shared states. Motion and GSAP provide animation primitives for more deliberate choreography. A precomposed interaction pattern starts further along: some of the structure, timing and behavior already exist, leaving the project to adapt rather than invent them.
A useful rule is to use native capabilities when the behavior is simple, use an animation engine when the choreography is custom, and evaluate a reusable source pattern when the interaction is familiar but expensive to compose repeatedly.
Three ways to start an interaction
| Native React / browser | Animation Engine | Source-first interaction pattern | |
|---|---|---|---|
| Starting material | CSS, Web Animations API, <ViewTransition> | Motion, GSAP or similar primitives | Existing component structure and interaction implementation |
| Good fit | State feedback, entrances, layout continuity, straightforward transitions | Gestures, timelines, coordinated states, custom choreography | Familiar but non-trivial interactions that still need project-specific adaptation |
| The team still owns | Composition beyond the primitive | Interaction architecture, structure and production adaptation | Adaptation, integration, testing and project-specific behavior |
Each step supplies more of the interaction's composition. It also changes which decisions still begin from zero.
Prebuilt vs custom is the wrong binary
“Prebuilt” might describe a sealed component with six props. It might also describe editable source copied directly into the application. “Custom” could mean a shader-driven WebGL experience, or three lines of CSS on a button.
Those labels say less about control than they first appear to.
Consider a route or layout transition. React 19.3 can coordinate enter, exit, update and shared transitions through <ViewTransition>. CSS controls the presentation, while event props can use the Web Animations API for imperative customization. React currently limits the component to DOM transitions, which also makes its boundary fairly clear.
Motion and GSAP solve a different problem. They provide animation primitives rather than a finished interaction composition. They become useful when several states, gestures or pieces of choreography have to agree.
A pinned product narrative adds another layer. The section may need viewport measurement, scroll progress, coordinated media changes, responsive behavior and a simpler mobile state. Starting from primitives gives the team control over every decision. Starting from an existing pattern means some of those decisions already have an implementation to inspect and change.
A practical decision matrix for React and Next.js teams
The choice becomes clearer when interaction novelty is compared with production burden.
| Interaction | Sensible starting point | Why |
|---|---|---|
| Button hover or press feedback | CSS/native | A small state change rarely justifies another runtime |
| Panel entrance or straightforward layout continuity | React <ViewTransition> / CSS | Native APIs may already express the required transition |
| Coordinated component states or gestures | Motion or similar engine | Declarative states, gesture handling and layout tooling reduce manual orchestration |
| Custom timeline or scroll choreography | GSAP/Motion or reusable interaction pattern | Timeline, lifecycle and measurement work begin to dominate |
| Familiar text reveal, cursor system or pinned feature sequence used repeatedly | Evaluate a source-first pattern | The composition is recognizable while project-specific adaptation still matters |
| Product-specific data or gesture interaction | Bespoke implementation | The unique behavior is the point |
| WebGL hero or shader-heavy visual system | Specialist implementation or verified source pattern | Rendering cost, device capability and fallback design matter regardless of origin |
Teams can move between these layers. A bespoke interaction repeated across several launches may eventually become an internal reusable component. A reusable pattern modified beyond recognition has effectively become custom code.
Start with the interaction job, not the implementation tool
A useful split is between motion that reports interface state and interaction that becomes part of the page structure.
A pressed button needs acknowledgement. A disclosure panel may need an entrance and exit. A selected card may need spatial continuity when its layout changes. These jobs stay close to browser state. A larger animation architecture can cost more than it removes.
Scroll storytelling, pointer-reactive systems and render-heavy scenes behave differently. A pinned sequence may depend on viewport measurement and scroll progress. A cursor trail requires precise pointer coordinates on desktop but has no equivalent input on touch. A WebGL hero introduces a canvas, render loop, DPR decisions, shader or texture cost and a separate fallback problem.
The contrast is less about visual ambition than implementation responsibility:
| Simple UI motion | Composed interaction system |
|---|---|
| State change starts the animation | Scroll, pointer or several states may drive it |
| Browser styles may be sufficient | Timeline or render orchestration may be required |
| Little or no layout measurement | Geometry may need measurement and refresh |
| Similar behavior can survive across inputs | Touch may need a different interaction |
| Cleanup is minimal | Listeners, observers, timelines or render loops need cleanup |
| Static state is obvious | Reduced-motion and fallback states need deliberate design |
A simple interaction can stay simple:
.cta {
transform: translateY(0);
transition: transform 160ms ease;
}
.cta:hover,
.cta:focus-visible {
transform: translateY(-2px);
}
@media (prefers-reduced-motion: reduce) {
.cta {
transition: none;
transform: none;
}
}
A pinned feature sequence is different. It may need a client-side component, element refs, timeline setup, resize handling, scroll cleanup, breakpoint-specific behavior and a static state when motion is reduced. The animation itself can be the easy part.
Where prebuilt interaction patterns earn their place
Reusable patterns become useful when the visual idea is familiar but its production implementation is not trivial.
A text reveal might begin with a small transform and opacity change. Real content introduces line wrapping, font loading, breakpoint changes and reduced-motion behavior. A scroll sequence accumulates more conditions because the animation is coupled to layout and input.
For an agency or product team, rebuilding those mechanics across projects can turn “custom animation” into repeated infrastructure work. Reuse changes the starting point; it does not remove adaptation.
A source-first model changes the trade-off because the implementation lands inside the project instead of remaining behind a fixed configuration surface. When the mobile breakpoint moves, the markup conflicts with the page, the easing feels wrong beside the rest of the interface or the fallback needs to change, the relevant code can be edited where the behavior lives.
A composed pattern can therefore contain more than timing values. It can include component structure, setup, styles, dependencies and the places where adaptation is expected.
For recurring jobs, teams can inspect existing text animation patterns or React scroll interaction patterns before committing to another blank implementation.
Where hand-built animation is the better engineering decision
There are equally clear cases where an existing pattern is unnecessary.
A visual state that can be expressed cleanly in CSS should usually stay close to CSS. The Web Animations API provides direct browser control when imperative timing is useful without requiring a broader animation framework.
Custom implementation also makes sense when the interaction itself is the novel part of the product. A visualization driven by live values, an unusual editing gesture or a brand transition built around a specific spatial model may share little useful structure with an existing composition. Adapting somebody else's implementation can become archaeology with nicer easing curves.
Animation engines remain useful here. Motion provides React-oriented animation components, variants, gestures and layout animation. GSAP offers timeline-driven choreography, and gsap.context() can collect scoped animations and ScrollTriggers so they can be reverted during cleanup; GSAP's React tooling builds on that lifecycle model.
Sometimes the shortest custom implementation is simply the cleanest architecture.
Compare production cost, not demo quality
An interaction demo has unusually favorable working conditions. The copy fits. The viewport was chosen deliberately. Nothing routes away halfway through the sequence. The pointer exists. The canvas is probably running on a capable desktop.
A production page removes those conveniences.
In a Next.js App Router project, animation components that require state, effects, event handlers or browser APIs belong behind a Client Component boundary. The 'use client' directive marks the client/server module boundary; it does not need to appear in every descendant file. Client Components can still be prerendered during the initial load, so a library that assumes window or document during rendering may require a genuinely browser-only loading strategy such as a dynamic import with SSR disabled.
Lifecycle work matters just as much. Scroll listeners, ResizeObserver instances, timelines and render loops need to leave with the component. Layout measurements should not run continuously unless the interaction requires them. Fonts, images and late-loading media need testing because changes in geometry can turn a polished sequence into visible layout shift.
Input changes the design too. A pointer attraction effect has no direct equivalent on touch. Shrinking the desktop interaction onto a phone does not solve that; the mobile state needs its own purpose.
Reduced motion is another branch rather than a universal on/off switch. prefers-reduced-motion exposes the user's request to reduce non-essential movement, but respecting it does not settle keyboard behavior, focus management or semantic structure.
Before shipping either reusable or bespoke animation, check:
- What browser APIs and dependencies does it introduce?
- What starts when the component mounts, and what is removed when it unmounts?
- Is layout measured repeatedly, and can media or font loading invalidate those measurements?
- Does work continue when the interaction is offscreen?
- What does touch or a coarse pointer receive instead?
- Does reduced motion preserve the content and usable state?
- Can controls still be reached and understood without animation?
- Does the implementation behave correctly in the project's target browsers?
- What happens on resize, route changes and real mid-range hardware?
A reusable implementation can reduce blank-file setup. The team still has to validate what happens on the real page.
React 19.3 gives native React more transition work
React 19.3, released September 9, 2026, moved <ViewTransition> from experimental to stable. React can coordinate DOM elements entering, exiting, moving or resizing around Transition updates, including shared transitions between matching elements. CSS can customize the transition classes, while event props can trigger Web Animations API behavior.
A team considering another abstraction solely to crossfade a mounted panel or preserve continuity between two representations of the same card should now include React's own capability in the evaluation.
It does not follow that Motion or GSAP have become redundant. Motion covers gestures, variants and layout-oriented orchestration beyond a single transition primitive. GSAP remains useful for timeline-heavy choreography. Nor does <ViewTransition> architect a scroll narrative, decide what a cursor interaction becomes on touch or manage the cost of a WebGL scene.
| <ViewTransition> can help with | It does not automatically solve |
|---|---|
| Enter and exit transitions | Scroll-linked storytelling |
| Moving/resizing DOM elements | Pointer-specific interaction systems |
| Shared DOM transitions | A complete branded motion system |
| CSS/WAAPI customization | WebGL render loops and GPU cost |
| React Transition integration | Touch fallback, accessibility or project-specific testing |
React 19.3 gives native React a larger share of straightforward transition work. The rest of the stack still has a job.
Where Vault fits in that decision
Hyperiux Vault occupies the source-first part of this model. Its workflow is built around previewing an interaction, adding its source files to the project, adapting that implementation and testing it in the real page context.
The underlying machinery varies by effect. Some patterns need React and CSS. Others can use Motion, GSAP, Three.js, React Three Fiber, canvas or WebGL. Vault keeps those dependencies attached to the interaction that requires them rather than treating one animation stack as mandatory for the entire catalogue.
That distinction matters when the interaction job is already recognizable. A developer may know GSAP perfectly well and still have little reason to architect the same pinned feature sequence from a blank component for another launch. In that case, the useful starting point is the composed implementation: component structure, motion setup and adaptation points expressed as editable source.
Source access does not remove production responsibility. The project still decides how the interaction is imported, bundled, adjusted for its content, simplified on mobile and reconciled with the rest of its frontend architecture.
If that is the problem in front of you, browse React interaction effects and inspect the implementation before rebuilding the pattern yourself.
If the behavior itself is the bespoke part of the project, use Vault's Request Custom Animation option from the Effects experience.
“Custom” is not a quality tier. Build the behavior that is genuinely unique; when the interaction is already a known pattern, decide whether another blank file is actually where the project should spend its engineering effort.




