rive-react

React components and hooks for loading, playing, and controlling Rive animations.

Library
npm
v4.34.1
1,155stars
MIT License

Repository Health

Pre-computed score based on development activity, maintenance, community, maturity, and trend momentum.How we score it →
85/100Excellent
Development Activity88
Maintenance96
Community56
Maturity60
Momentum40

Technical Analysis

AI-assessed by reading the actual repository — architecture, code quality, innovation, and documentation.How we score it →
80/100Excellent
Architecture78
Code Quality82
Innovation80
Learning Curve80

Rive React is the official React wrapper around Rive’s JS/Wasm runtime, giving React apps a <Rive /> component plus a family of hooks (useRive, useRiveFile, useStateMachineInput) for loading interactive vector animations exported from the Rive editor. It handles canvas sizing, device-pixel-ratio scaling, and pausing playback when an animation scrolls off screen, so consumers don’t have to wire up ResizeObserver or IntersectionObserver themselves.

Beyond basic playback, the library exposes hooks for Rive’s Data Binding system — useViewModel, useViewModelInstance, and per-type property hooks like useViewModelInstanceNumber and useViewModelInstanceBoolean — letting components read and write typed state machine inputs and view-model properties directly. The package is published in three ecosystem variants (@rive-app/react-canvas, @rive-app/react-webgl2, @rive-app/react-canvas-lite) that swap the underlying rendering backend while sharing the same hook API, so teams can trade off bundle size against GPU-accelerated rendering without changing application code.

What You Get

  • A <Rive /> component and matching useRive hook that load a .riv file onto a canvas and return the live Rive instance for imperative control
  • Automatic canvas resizing and device-pixel-ratio handling via useResizeCanvas and useDevicePixelRatio, so animations stay crisp without manual observer setup
  • Built-in IntersectionObserver support that pauses playback when the animation scrolls out of view, reducing wasted CPU/GPU work
  • useStateMachineInput for driving Rive state machine booleans/numbers/triggers directly from React state or event handlers
  • A full set of Data Binding hooks (useViewModel, useViewModelInstance, and typed property hooks for number/string/boolean/color/enum/trigger/image/font/list/artboard) for reading and writing view-model properties
  • useRiveFile for loading a Rive file once and reusing it across multiple mounted animation instances

Common Use Cases

  • Embedding interactive product animations (onboarding flows, empty states, celebratory micro-interactions) that respond to user actions via state machine inputs
  • Building animated icon sets or illustrations where a single source .riv file drives many instances on a page via useRiveFile
  • Data-driven dashboards or games where numeric or boolean view-model properties are bound to live application data through the Data Binding hooks
  • Marketing and landing pages that need lightweight, interruptible animations which pause automatically when scrolled out of the viewport

Under The Hood

Architecture The package’s entry point (src/index.ts) re-exports a <Rive /> component and a layered set of hooks built around one core primitive, useRive (src/hooks/useRive.tsx), which wires together callback refs for the container/canvas, useResizeCanvas and useDevicePixelRatio for responsive sizing, and useIntersectionObserver to pause rendering when off screen. A notable architectural subtlety lives in useRive.tsx and bindScheduler.ts: the underlying runtime supports both an offscreen (shared-context) renderer and a per-canvas GPU renderer, and a Rive file’s rendering mode is fixed at import time and takes precedence over an instance’s own option — the hook explicitly reconciles the caller’s explicit useOffscreenRenderer choice against a riveFile’s deferredRequested flag and warns rather than silently misrendering. useRiveFile.ts separates loading a shared file from instantiating it, and the newer Data Binding hooks (useViewModel, useViewModelInstance, and per-type property hooks) resolve instances through a dedicated resolveViewModelInstance.ts helper. Teardown paths are funneled through a safeCleanup utility that swallows and warns on GPU-driver-dependent cleanup errors instead of letting them escape into React’s render cycle.

Tech Stack Written entirely in TypeScript, targeting React ^16.8.0 through ^19.0. The published packages depend on one of three sibling runtime packages (@rive-app/canvas, @rive-app/webgl2, @rive-app/canvas-lite), each the JS/Wasm core the React layer wraps. The repo is a monorepo: a root rive-react package plus per-renderer packages under npm/ (react-canvas, react-webgl2, react-canvas-lite), built with bunchee into dist/ with generated type declarations, and an examples/ Storybook workspace for manual verification. Release automation runs through release-it.

Code Quality A dozen Jest + React Testing Library test files cover the core hooks (useRive, useRiveFile, state machine inputs, GPU canvas mode, intersection-observer pausing, the render scheduler) as well as the <Rive /> component itself. GitHub Actions CI runs type-checking (tsc --noEmit), ESLint, the Jest suite, and a production build on every push, so regressions in any of those are caught before merge. Source is fully typed with dedicated exported types (RiveState, UseRiveParameters, UseRiveOptions), and several hooks carry deliberate reasoning comments about non-obvious runtime behavior (GPU Canvas vs. offscreen-renderer conflicts) rather than only restating what the code does.

API Design Rather than one monolithic component, the library exposes a hook per concern — a base useRive alongside narrowly-typed Data Binding hooks (useViewModelInstanceNumber, ...Boolean, ...Color, ...Enum, ...Trigger, ...Image, ...Font, ...List, ...Artboard) that mirror Rive’s newer property-binding model with type-safe getters/setters instead of one generic accessor. It re-exports the underlying runtime package’s types so consumers rarely need a separate import, and the three renderer-specific packages share one hook surface, letting teams switch rendering strategy without touching component code.

Join founders buildingwith open source

Opinionated takes, migration guides, cost-saving tips, and insights from the open source ecosystem.

Subscribe on Substack
Join 750+ subscribers

Search