Skip to main content

Migrating from rive-react-native to @rive-app/react-native

The new Rive React Native runtime (@rive-app/react-native) is a complete rewrite built with Nitro Modules for improved performance and better React Native integration.
All your Rive graphics will still look and function the same as they did before.

What’s New

RiveFile Ownership: You now own the RiveFile object via the useRiveFile hook, enabling file caching, multiple instances from one file, and better resource management.
// Old: file managed internally
<Rive url="https://cdn.rive.app/animations/vehicles.riv" />

// New: you own the RiveFile
const { riveFile } = useRiveFile(require("./vehicles.riv"));
<RiveView file={riveFile} />
Enhanced Data Binding: Direct access to ViewModel and ViewModelInstance objects, enabling initialization hooks, multiple instances, and support for all property types (lists, images, artboards).
// Old: hooks take riveRef, return tuples
const [setRiveRef, riveRef] = useRive();
const [health, setHealth] = useRiveNumber(riveRef, "health");

// New: hooks take viewModelInstance, return objects
const viewModelInstance = useViewModelInstance(riveFile);
const { value: health, setValue: setHealth } = useRiveNumber(
  "health",
  viewModelInstance
);
Improved Error Handling: Error handling is improved. See the error handling documentation for more information.

Requirements

  • React Native: 0.78+ (0.79+ recommended)
  • Expo SDK: 53+ (for Expo users)
  • iOS: 15.1+
  • Android: SDK 24+
  • Xcode: 16.4+
  • JDK: 17+
  • Nitro Modules: 0.25.2+

Migration Steps

1. Installation

npm uninstall rive-react-native
npm install @rive-app/react-native react-native-nitro-modules
react-native-nitro-modules is required as this library relies on Nitro Modules.

2. Update Imports

// Old
import Rive from "rive-react-native";

// New
import { RiveView } from "@rive-app/react-native";

3. Loading Rive Files

const { riveFile, isLoading, error } = useRiveFile(require('./animation.riv'));
// Also supports: URL string, resource name, or ArrayBuffer

return <RiveView file={riveFile} style={{ width: 400, height: 400 }} />;
See loading Rive files for more information.

4. Component Migration

<RiveView
  file={riveFile}
  artboardName="MainArtboard"
  stateMachineName="State Machine 1"
  fit={Fit.Contain}
  autoPlay={true}
  style={{ width: 400, height: 400 }}
/>
See React Native runtime and props documentation for more information.

5. View Reference Migration

const { riveViewRef, setHybridRef } = useRive();

riveViewRef?.play();
riveViewRef?.pause();

<RiveView hybridRef={setHybridRef} file={riveFile} />
See Rive ref methods for more information.

6. State Machine Inputs (Deprecated)

These methods are deprecated. Migrate to data binding instead.
riveViewRef?.setNumberInputValue('level', 5);
riveViewRef?.setBooleanInputValue('isActive', true);
riveViewRef?.triggerInput('buttonPressed');
See state machine inputs for more information.

7. Rive Events (Deprecated)

These methods are deprecated. Use data binding triggers instead.
useEffect(() => {
  const handleEvent = (event: RiveEvent) => console.log(event);
  riveViewRef?.onEventListener(handleEvent);
  return () => riveViewRef?.removeEventListeners();
}, [riveViewRef]);
See runtime events for more information.

8. Data Binding

The new runtime significantly improves data binding by giving you direct access to ViewModelInstance objects. This enables:
  • Initialization hooks - Set initial property values before rendering with onInit callback
  • Multiple instances - Create and manage multiple view model instances from the same file
  • Advanced property types - Full support for lists, images, artboards, and nested view models
  • Better React integration - Property hooks integrate seamlessly with React state and lifecycle
Main API changes:
  • Property hooks take viewModelInstance instead of riveRef
  • Hooks return objects instead of tuples
  • Parameters are swapped: (path, viewModelInstance) vs (riveRef, path)
const { riveFile } = useRiveFile(require('./animation.riv'));
const viewModelInstance = useViewModelInstance(riveFile);

const { value: health, setValue: setHealth } = useRiveNumber('health', viewModelInstance);
const { value: name, setValue: setName } = useRiveString('Player/Name', viewModelInstance);
const { trigger } = useRiveTrigger('gameOver', viewModelInstance, {
  onTrigger: () => console.log('Game Over!')
});

<RiveView file={riveFile} dataBind={viewModelInstance} />
See data binding for more information.

9. Out of Band Assets

const { riveFile } = useRiveFile(
  require('./animation.riv'),
  {
    referencedAssets: {
      'Inter-594377': {
        source: require('./fonts/Inter-594377.ttf'),
      },
      'my-image': {
        source: { uri: 'https://example.com/image.png' },
      },
    },
  }
);
See loading assets for more information.

10. Text Run Updates (Deprecated)

Direct text run methods (.setTextRunValue(), .getTextRunValue()) are deprecated. Migrate to data binding strings instead.
See text runs for more information.

11. Callbacks

<RiveView
  file={riveFile}
  onError={(error) => console.error('Rive error:', error)}
/>

// For state changes, use data binding listeners. For example, a trigger:
const { trigger } = useRiveTrigger('onStateChange', viewModelInstance, {
  onTrigger: () => console.log('State changed')
});
See data binding for more information.

Getting Help

If you encounter issues:
  1. Check the new runtime documentation
  2. Review the Data Binding guide
  3. See the example app
  4. Visit the Rive community forums
  5. Report issues on GitHub