Migrating from 1.x to 2.x

Migration from Reanimated 3.x to 4.x

Migration Steps

Upgrade the react-native-reanimated package:

npm
yarn
pnpm
bun
npm install react-native-reanimated

Install the react-native-worklets package:

npm
yarn
pnpm
bun
npm install react-native-worklets

Update Configuration

Expo

Run prebuild to update the native code in the ios and android directories.

npm
yarn
pnpm
bun
npm expo prebuild

And that's it! Reanimated 4 is now configured in your Expo project.
Since Expo SDK 50, the Expo starter template includes the Reanimated Babel plugin by default.

React Native CLI

When using the React Native Community CLI, you also need to manually add the react-native-worklets/plugin plugin to your babel.config.js.

babel.config.js
module.exports = {
  presets: [
    ... // don't add it here :)
  ],
  plugins: [
    ...
    // for web
    '@babel/plugin-proposal-export-namespace-from',
-   'react-native-reanimated/plugin',
+   'react-native-worklets/plugin',
  ],
};

Remove wrapWithReanimatedMetroConfig from your metro.config.js.

metro.config.js
- const { wrapWithReanimatedMetroConfig } = require('react-native-reanimated/metro-config');

const config = {
  // Your existing Metro configuration options
};

- module.exports = wrapWithReanimatedMetroConfig(config);
+ module.exports = config

Remove currentIndex and totalCount from useGestureViewerController

❗ Breaking Change
  • useGestureViewerController no longer returns currentIndex and totalCount. Use useGestureViewerState instead.
  • Rename GestureViewerControllerState type to GestureViewerState
import {
  GestureViewer,
- GestureViewerControllerState,
+ GestureViewerState
  useGestureViewerController,
  useGestureViewerEvent,
+ useGestureViewerState,
} from 'react-native-gesture-image-viewer';

const { 
  goToIndex, goToPrevious, goToNext, zoomIn, zoomOut, resetZoom, rotate,
- currentIndex, totalCount
} = useGestureViewerController();

+ const { currentIndex, totalCount } = useGestureViewerState();

Remove onIndexChange prop

❗ Breaking Change

onIndexChange prop has been removed. Use useGestureViewerState with useEffect instead.

// Before
<GestureViewer onIndexChange={(index) => console.log(index)} />

// After
const { currentIndex } = useGestureViewerState();

useEffect(() => {
  console.log(currentIndex);
}, [currentIndex]);

Rename gesture props

Improve gesture prop naming for better developer experience.

❗ Breaking Change
  • enableDismissGesturedismiss.enabled
  • dismissThresholddismiss.threshold
  • resistancedismiss.resistance
  • animateBackdropdismiss.fadeBackdrop
  • useSnapenableSnapMode
  • enableZoomPanGestureenablePanWhenZoomed
  • enableZoomGestureenablePinchZoom
  • enableSwipeGestureenableHorizontalSwipe
<GestureViewer
-  enableDismissGesture
-  dismissThreshold
-  resistance
-  animateBackdrop
+  dismiss={{
+    enabled: true,
+    threshold: 80,
+    resistance: 2,
+    fadeBackdrop: true,
+  }}

-  useSnap
+  enableSnapMode

-  enableZoomPanGesture
+  enablePanWhenZoomed

-  enableZoomGesture
+  enablePinchZoom

-  enableSwipeGesture
+  enableHorizontalSwipe
/>