Migrating React Native Reanimated 2 to 3 without breaking every screen
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.
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:
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:
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:
New:
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.
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:
- Imports. The location of
FadeIn,SlideInLeft, and friends moved. They're now exported from the top-levelreact-native-reanimatedpackage, not fromreact-native-reanimated/layoutAnimations. - Custom layout animations. If you wrote your own using the v2 API, the function signatures changed. The migration is documented; expect a small amount of work per custom animation.
- Behavior on screens that mount conditionally. Some edge cases of "this animated component re-mounts" produce different results in v3. Re-test screens that conditionally render animated content.
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:
New:
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 API | v3 status | Migration |
|---|---|---|
| useAnimatedGestureHandler | Deprecated | Use Gesture Handler v2's Gesture API |
| useDerivedValue | Same name, same behavior | No change |
| useAnimatedStyle | Same name, same behavior | Worklet directive becomes optional |
| useSharedValue | Same name, slight default change | Initial value handling tightened; explicit defaults safer |
| useAnimatedReaction | Same name, same behavior | Worklet directive becomes optional |
| useAnimatedProps | Same name, same behavior | Worklet directive becomes optional |
| useScrollViewOffset | New in v3 | Can replace useAnimatedScrollHandler in some cases |
Common errors and fixes
- "Reanimated 3 failed to create a worklet" at runtime. Almost always the Babel plugin position. Make it the last plugin.
- Layout animation doesn't fire. Import path changed, or the parent component is re-mounting in a way v3 handles differently. Add an explicit
keyprop, or wrap in a fragment to stabilize the tree. - Gesture handler crashes on Android. Usually
react-native-gesture-handlerbelow v2.14, paired with a v3 Reanimated. Upgrade Gesture Handler. - "Cannot find module 'react-native-reanimated/plugin'". The Babel cache. Clear:
npx react-native start --reset-cache. - iOS build fails after upgrade. Old podspec cache. Delete
ios/Podsandios/Podfile.lock, thenpod installagain. - Hot reload stops updating worklets. Known limitation when refining worklet detection. Full reload (cmd-R) recovers.
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:
- Every screen with a layout animation (enter, exit, position transition)
- Every gesture-driven UI (swipe to dismiss, pan-to-pull, pinch-to-zoom)
- Every scroll-driven animation (parallax header, sticky header reveal)
- Every shared element transition or "hero" animation across screen boundaries
- Anything driven from
useAnimatedReactionor chained derived values
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.