skip to content

Why does Reanimated 4 need react-native-worklets, the Worklets Babel plugin and the New Architecture before any worklet runs?

level: middleimportance: should knowfreq 38%

answer

  1. worklets moved to their own package
  2. a Babel pass that workletizes functions
  3. react-native-worklets/plugin, listed last
  4. Failed to create a worklet
  5. Fabric only, Paper dropped

basics

~20 s

Reanimated 4 moved its worklet runtime into react-native-worklets, whose Babel plugin turns worklet functions into serializable objects the UI runtime can run. It also dropped the legacy Paper renderer, so it runs only on the New Architecture.

solid answer

~40 s

In Reanimated 4 the worklet machinery lives in a separate package, `react-native-worklets`, which you install at the version the compatibility table pairs with your Reanimated (4.7 pairs with 0.13.x) and rebuild natively. Its Babel plugin, `react-native-worklets/plugin`, finds functions marked `'worklet'` and the callbacks of hooks like `useAnimatedStyle`, and turns them into serializable objects that can be copied to the UI runtime; without it you get "Failed to create a worklet". In a React Native CLI app you add it last in `babel.config.js` and reset Metro's cache; Expo's default Babel setup already includes it. Reanimated 4 supports only the New Architecture because it dropped the legacy Paper renderer and applies updates through Fabric's shadow tree. On React Native 0.82 and later that is the only architecture anyway.

code

javascript · 7 lines
javascript
module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: [
    // any other plugins go before it
    'react-native-worklets/plugin',
  ],
};

go deeper

for a junior

Recall the install steps: both packages, the Worklets Babel plugin last in babel.config.js for CLI apps, a cache reset and a native rebuild.

for a middle

Explain what workletization is, which callbacks the plugin converts automatically, and why a function passed by reference needs its own worklet directive.

for a senior

Diagnose setup failures from their messages: missing plugin, stale cache, JS and native version mismatch, and Expo Go's pinned Worklets version, and plan upgrades against the compatibility table.

for a principal

Weigh the upgrade path for a codebase still on Reanimated 3: the New Architecture migration it implies, the renamed worklet APIs and the changed spring defaults, and how to stage it.

## Three prerequisites, three jobs A Reanimated 4 animation needs three things to be true before a single worklet can run: | Prerequisite | Its job | Symptom when it is missing | |---|---|---| | `react-native-worklets` installed and built | Provides the UI runtime, worklet serialization and `scheduleOnRN` / `scheduleOnUI` | Errors that the native part of Worklets is not initialized or does not match | | Worklets Babel plugin in the build | Converts worklet functions at compile time | "Failed to create a worklet" | | New Architecture | The renderer Reanimated 4 is built against | Reanimated 4 does not support the legacy renderer at all | ## Why worklets became their own package Up to Reanimated 3, worklets were part of Reanimated. In Reanimated 4 they moved to **`react-native-worklets`** for modularity, so other libraries can create worklet runtimes too. Consequences for a project: - You install **both** packages and rebuild the native app; a JS-only reload is not enough after adding or upgrading them. - Versions must match the **compatibility table**: Reanimated 4.7.x pairs with `react-native-worklets` 0.13.x and supports React Native 0.86 to 0.88. - In **Expo Go** you must use the exact Worklets version bundled into that Expo SDK, because you cannot rebuild Expo Go's native code. - Worklet helpers are imported from `react-native-worklets`: `scheduleOnRN` replaces `runOnJS`, `scheduleOnUI` replaces `runOnUI`, `runOnUISync` replaces `executeOnUIRuntimeSync`, and `createSerializable` replaces `makeShareableCloneRecursive`. The old names are still re-exported from Reanimated but are deprecated. ## What the Babel plugin actually does A **worklet** is a short-running JavaScript function that can be moved to and executed on another JavaScript runtime. Closures cannot simply be handed to a different runtime, so the **Worklets Babel plugin** rewrites them at build time into serializable objects that carry their code and the variables they capture. This is called **workletization**. The plugin workletizes: - any function whose body starts with the `'worklet'` directive; - callbacks passed inline to Reanimated hooks such as `useAnimatedStyle` and `useDerivedValue`, and the completion callbacks of `withTiming` and `withSpring`; - gesture callbacks written inline in a Gesture Handler configuration. Gesture Handler's docs spell out the limit of that automatic pass: a gesture callback defined elsewhere and passed by reference, or wrapped in `useCallback` or `useMemo`, is not picked up and needs its own `'worklet'` directive. The same directive inside `useCallback` is the documented replacement for the removed `useWorkletCallback`. ## Setting it up 1. Install `react-native-reanimated` and `react-native-worklets`. 2. **React Native CLI**: add `'react-native-worklets/plugin'` to `plugins` in `babel.config.js`, and make it the **last** entry. It is a plugin, not a preset. 3. **Expo**: the default Babel configuration already includes the plugin, so an Expo app normally needs no Babel change. 4. Reset Metro's cache (`npm start -- --reset-cache`, or `npx expo start -c`) so previously transformed files are rebuilt with the plugin. 5. Rebuild the native app (`pod install` on iOS for a CLI project, or `npx expo prebuild` and a new build for Expo). `react-native-reanimated/plugin` still exists as a compatibility export, but the docs recommend the Worklets plugin directly. If a dependency ships code transformed by an older plugin version, you can see a mismatch error between the JavaScript code version and the plugin version; resetting the cache is the first fix. ## Why only the New Architecture Reanimated 4 dropped support for the legacy architecture and its renderer, **Paper**. It applies animated updates through the New Architecture renderer, **Fabric**: by default it clones shadow nodes and commits them to the shadow tree, with an opt-in fast path that applies non-layout props such as `transform` and `opacity` directly on each platform. Code built against that model has nothing to call on Paper. In practice this is rarely a blocker today: since React Native 0.82 the New Architecture is the only architecture and cannot be turned off, so any 0.87 app satisfies it. The question still comes up in interviews about upgrades, where the answer is that Reanimated 3 was the legacy-architecture option and is no longer actively maintained. ## Common setup failures - **Plugin missing or not last**: "Failed to create a worklet" at the first animated hook. - **Package upgraded without a native rebuild**: an error about the JavaScript and native parts of Worklets not matching. - **Stale Metro cache** after adding the plugin: code still runs untransformed until the cache is cleared.

  • Why can a Gesture Handler callback wrapped in useCallback fail on the UI runtime when the same callback written inline works?
    The Worklets Babel plugin auto-workletizes gesture callbacks written inline in the gesture configuration. A function defined elsewhere or wrapped in `useCallback` or `useMemo` is not detected, so it stays a plain JS function that cannot run as a worklet. Put the `'worklet'` directive at the top of its body.
  • After upgrading react-native-worklets you reload the JS bundle and see a version mismatch error. What went wrong?
    The package has a native part. Reloading only replaces the JavaScript, so the app still runs the previous native code. Rebuild the native app, and in Expo Go use exactly the Worklets version bundled with that SDK, since Expo Go's native code cannot be rebuilt.

saying these in an interview costs you the question

  • Installing react-native-reanimated alone is enough, since it bundles worklets as in version 3.
  • The Worklets plugin belongs in the presets array of babel.config.js.
  • Babel plugin order never matters, so the Worklets plugin can go anywhere.
  • A JS reload is enough after adding react-native-worklets.
  • Reanimated 4 can run on the legacy Paper renderer if Hermes is enabled.
  • react-native-reanimated/plugin is still the recommended plugin name in Reanimated 4.