Search code examples
androidiosreact-nativebabeljsreact-native-reanimated

"Did you forget to add Reanimated Babel plugin in babel.config.js?"


How can I resolve the following error?

Error: Failed to create a worklet. Did you forget to add Reanimated Babel plugin in babel.config.js? See installation docs at https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/installation#babel-plugin. 1

"Error: Failed to create a worklet."

Background

In an Expo app, I followed the instructions on how to install a drawer navigator : 2

  1. npm install @react-navigation/native
  2. npm install @react-navigation/drawer
  3. npm install react-native-gesture-handler react-native-reanimated

I then went on to try a minimal example of drawer-based navigation.
It's a simple application that can be run online.
The minimal example has merely one file containing React Native code, which contains a HomeScreen and a NotificationsScreen, in addition to the main App component.

Out of precaution, I started the project with a command that cleans the npm cache : 3

npm start -- --reset-cache

I then pressed a for Android (it's i for iOS) and r to reload.
Every time I do this, I get the error shown in the screenshot above. 4


babel.config.js :

module.exports = function (api) {
  api.cache(true);
  return {
    presets: ['babel-preset-expo'],
  };
};

App.js :

import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';

function HomeScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button
        onPress={() => navigation.navigate('Notifications')}
        title="Go to notifications"
      />
    </View>
  );
}
function NotificationsScreen({ navigation }) {
  return (
    <View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
      <Button onPress={() => navigation.goBack()} title="Go back home" />
    </View>
  );
}
const Drawer = createDrawerNavigator();
export default function App() {
  return (
    <NavigationContainer>
      <Drawer.Navigator initialRouteName="Home">
        <Drawer.Screen name="Home" component={HomeScreen} />
        <Drawer.Screen name="Notifications" component={NotificationsScreen} />
      </Drawer.Navigator>
    </NavigationContainer>
  );
}

package.json :

{
  "name": "reanimated-demo",
  "main": "node_modules/expo/AppEntry.js",
  "scripts": {
    "start": "expo start",
    "android": "expo start --android",
    "ios": "expo start --ios"
  },
  "dependencies": {
    "@react-navigation/drawer": "^6.6.4",
    "@react-navigation/native": "^6.1.8",
    "expo": "~49.0.13",
    "react": "18.2.0",
    "react-native": "0.72.5",
    "react-native-gesture-handler": "~2.12.0",
    "react-native-reanimated": "~3.3.0"
  },
  "overrides": {
    "semver": "^7.5.4"
  }
}

References


1 The link in the error message leads to a Page Not Found page.

2 The corresponding Yarn commands are :

a. yarn add @react-navigation/native
b. yarn add @react-navigation/drawer
c. yarn add react-native-gesture-handler react-native-reanimated

3 For Yarn, the command is yarn start --reset-cache.

4 To reproduce: download and unzip to some directory of your choice.
Switch to that directory and run npm install and then npm start -- --reset-cache.
(You'll also need an emulator or a physical device on which you run the application.)


Solution

  • To resolve the error, there are two things you must do.

    1. Add 'react-native-reanimated/plugin' as the last plugin in babel.config.js.
      In your case, the updated file will be :
    module.exports = function (api) {
      api.cache(true);
      return {
        presets: ['babel-preset-expo'],
        plugins: ['react-native-reanimated/plugin'],
      };
    };
    
    1. You must clear the cache when restarting the server, exactly what you already do :
    npm start -- --reset-cache
    

    Note that you must do both those steps.
    If you omit one of them, the Reanimated error will prevail. 1

    The Reanimated error has been resolved.

    Why you got the error

    The instructions on how to install a drawer navigator are missing the two steps above that you must take to avoid the error. The steps I refer to, are called step 2 and step 3 in the documentation on how to install Reanimated. 2

    References


    1 No npm package should ever depend on what is in the cache. Unfortunately, the Reanimated package violates this rule. It's not a big deal, now that you know how to work around it.
    Just add plugins: ['react-native-reanimated/plugin'], to your babel.config.js,
    and then clean the cache when starting the server, npm start -- --reset-cache.
    If you're not happy with that, you'll need to find and fix the bug and then make a pull request.

    2 Reanimated's step 1 is to install the react-native-reanimated package itself.
    You already did that when following the instructions on how to install the drawer navigator.