Dependencies · Animation

Migrating React Native Reanimated 2 to 3 without breaking every screen

Published May 20, 2026 · 9 minute read
TL;DR

Reanimated 3 launched in late 2022 and has been the current major version for years. Reanimated 2 doesn't support the React Native New Architecture, which is now the default in 0.76+.

The migration is mostly mechanical. Layout animations, gesture handler integration, the Babel plugin location, and a few hook names — those are the surface area you'll touch.

Worklet ergonomics improved in v3. Most code gets shorter, not longer. Don't treat the migration as a rewrite; treat it as cleanup.

If you're on Reanimated 2 in 2026, you're not on the supported animation library anymore. Every React Native upgrade is harder than it should be. Every New Architecture migration is blocked until this is done.

The migration is finite. A few days for a typical app. This is the map.

On this page
  1. Why this is unavoidable now
  2. Install and Babel plugin
  3. Worklets: less ceremony
  4. Layout animations: rebuilt
  5. Gesture handler integration
  6. Hooks that changed
  7. Common errors and fixes
  8. Testing the migration
  9. FAQ

Why this is unavoidable now

Reanimated 2 doesn't run under the React Native New Architecture. The New Architecture has been the default since 0.76. If your app is on 0.76 or later — which it should be, for security and platform support reasons — Reanimated 2 will not work.

It also doesn't get fixes. The Reanimated team ships against v3. Bugs filed against v2 get closed with a "please upgrade" reply.

You can stay on Reanimated 2 only as long as you stay on React Native 0.73 or earlier. Which means you're stuck on a React Native version that's increasingly absent from security updates, library compatibility tables, and platform documentation.

Install and Babel plugin

Update the package:

npm install react-native-reanimated@latest cd ios && pod install

The Babel plugin moved from react-native-reanimated/plugin to the same path — that path stayed the same. What changed is that it must be the last plugin in your Babel config.

Open babel.config.js:

module.exports = { presets: ['module:metro-react-native-babel-preset'], plugins: [ // ...other plugins... 'react-native-reanimated/plugin', // must be last ], };

If you've added plugins after Reanimated in the past, move them above. The plugin transforms worklets, and if anything runs after it, you'll get cryptic runtime errors.

Worklets: less ceremony

Reanimated 2 required you to mark every worklet function with a 'worklet' directive on the first line. Reanimated 3 detects worklets automatically in most contexts. You can remove the directives from functions passed directly to useAnimatedStyle, useAnimatedProps, gesture callbacks, and similar APIs.

Old:

const animatedStyle = useAnimatedStyle(() => { 'worklet'; return { opacity: opacity.value }; });

New:

const animatedStyle = useAnimatedStyle(() => { return { opacity: opacity.value }; });

You still need the directive when defining a standalone function that will be used as a worklet later, and when calling JS code from the UI thread via runOnJS. The compiler error messages are clear about which case you're in.

Practical note

Don't go on a directive-stripping rampage. The directives that remain in your code after a normal migration are usually the ones that genuinely need to stay. Remove them only when the compiler explicitly stops complaining.

Layout animations: rebuilt

This is the biggest surface area in the migration. The layout animations API (entering, exiting, and layout transitions) was overhauled. The named animations (FadeIn, SlideInLeft, etc.) still exist but their underlying implementation is different.

Three things to verify:

Gesture handler integration

useAnimatedGestureHandler is deprecated. The replacement is to use Gesture Handler v2's API (Gesture.Pan(), Gesture.Tap(), etc.) and pass animated callbacks directly.

Old:

const gestureHandler = useAnimatedGestureHandler({ onStart: (_, ctx) => { ctx.startX = x.value; }, onActive: (e, ctx) => { x.value = ctx.startX + e.translationX; }, }); return ( <PanGestureHandler onGestureEvent={gestureHandler}> <Animated.View style={animatedStyle} /> </PanGestureHandler> );

New:

const startX = useSharedValue(0); const pan = Gesture.Pan() .onStart(() => { startX.value = x.value; }) .onUpdate((e) => { x.value = startX.value + e.translationX; }); return ( <GestureDetector gesture={pan}> <Animated.View style={animatedStyle} /> </GestureDetector> );

This often means upgrading react-native-gesture-handler at the same time. Pin v2.14 or later for clean v3 compatibility.

Hooks that changed

v2 APIv3 statusMigration
useAnimatedGestureHandlerDeprecatedUse Gesture Handler v2's Gesture API
useDerivedValueSame name, same behaviorNo change
useAnimatedStyleSame name, same behaviorWorklet directive becomes optional
useSharedValueSame name, slight default changeInitial value handling tightened; explicit defaults safer
useAnimatedReactionSame name, same behaviorWorklet directive becomes optional
useAnimatedPropsSame name, same behaviorWorklet directive becomes optional
useScrollViewOffsetNew in v3Can replace useAnimatedScrollHandler in some cases

Common errors and fixes

Testing the migration

Animation regressions don't show up in unit tests. The migration's test plan is manual exercise of the screens that use animations.

The screens to hit:

Smooth on iOS doesn't imply smooth on Android. Test both. Test on a low-end Android device, not just an emulator. Frame drops that look like jank on a Pixel 3a often look fine on flagship hardware.

Stuck mid-Reanimated migration?

The 2→3 upgrade is one of the most common stalling points during a React Native upgrade. We've shipped it across dozens of codebases. Run the free scanner to see the rest of the dependency graph, then get a fixed-price quote.

Frequently Asked Questions

What's new in React Native Reanimated 3?

Reanimated 3 launched in late 2022 and is the current major version. The big changes vs v2: cleaner worklet syntax (no more 'worklet' directive needed in most cases), New Architecture support, shared element transitions, an overhauled layout animations API, and a complete rewrite of the underlying C++ runtime for better performance under Fabric. The mental model is the same; the surface area is cleaner.

Is Reanimated 2 still supported?

Effectively no. Reanimated 2 receives no new features. It doesn't support the React Native New Architecture, which is now the default in 0.76+. Apps that upgrade React Native past 0.74 typically have to upgrade Reanimated to v3 as part of the same effort. If you're still on Reanimated 2 in 2026, the upgrade is overdue and is gating your ability to stay current on React Native.

How long does a Reanimated 2 to 3 migration take?

For a typical app with 20–50 animated components, plan a few days of focused work. Most components migrate with minimal changes — the breaking changes are clustered around layout animations, the useSharedValue defaults, and a few renamed hooks. Apps with custom worklets, complex shared-element transitions, or animation logic that reaches into Reanimated internals will take longer.

What are the breaking changes from Reanimated 2 to 3?

Notable ones: the layout animations API was rebuilt — old layout-animation entries (FadeIn, SlideInLeft, etc.) work but the underlying implementation changed and edge-case behavior is different. The 'worklet' directive is no longer required in most places (Reanimated detects them automatically). useAnimatedGestureHandler is deprecated in favor of integrating with Gesture Handler v2's API. Some hook signatures changed slightly. The Babel plugin moved. Each change has a documented migration step.

Does Reanimated 3 require the New Architecture?

No. Reanimated 3 works on both legacy and New Architecture. Performance is better under New Architecture because the JSI integration is more direct. If you're planning to migrate to the New Architecture, get Reanimated to v3 first — it's the supported configuration. Reanimated 2 + New Architecture is not a supported combination.

How do I check if my code uses Reanimated 2 patterns?

Search for useAnimatedGestureHandler — it's deprecated in v3. Search for 'worklet' directives in places where they aren't strictly required. Search for old layout-animation imports from react-native-reanimated/layoutAnimations — those moved. Search for any direct interaction with the Reanimated internals or runOnUI patterns that may have changed signatures. A grep pass through the codebase gives you a usable migration checklist.