React Native Reanimated Fix: Can't Resolve Module bs-less-plugin and Babel Plugin Errors
Fix "Can't resolve module bs-less-plugin" and Babel plugin errors in React Native Reanimated. Covers react-native-reanimated/plugin not found, Babel config issues, Metro bundler failures, and version compatibility for Expo and bare React Native projects. Updated 2026.
On this page
While building a React Native or Expo app that uses react-native-reanimated, you may encounter Metro or Babel errors related to `bs-less-plugin`, the Reanimated Babel plugin, or module resolution failures during bundling. These errors usually appear after installing or upgrading Reanimated, updating Babel config, upgrading React Native or Expo SDK, or when the Reanimated Babel plugin version does not match the runtime library. The build either fails during Metro bundling or the app crashes at runtime with worklet-related errors.
The Error
You may also see `worklet functions can only be used on the UI thread`, `__reanimatedWorkletInit is not a function`, or `ReanimatedError: Trying to access property 'default' of undefined` at runtime even when the build succeeds.
What Causes This Error
React Native Reanimated uses a custom Babel plugin to transform worklet functions at build time. This plugin rewrites functions marked with the `worklet` directive so they can run on the UI thread. When the Babel plugin is missing, misconfigured, or from a different version than the Reanimated runtime library, Metro cannot transform worklets and the build fails. The `bs-less-plugin` error specifically comes from an internal dependency of the Reanimated Babel plugin that cannot be resolved in certain configurations.
- react-native-reanimated/plugin not added to babel.config.js
- Reanimated Babel plugin version does not match the runtime library version
- Stale Metro cache still using old Babel transform after config change
- bs-less-plugin module missing from node_modules after partial install
- Babel config syntax error or incorrect plugin format
- Multiple conflicting versions of Reanimated in node_modules
- Expo SDK version expects a different Reanimated version
- Reanimated plugin placed before other required Babel plugins
Fix 1: Add Reanimated Babel Plugin Correctly
The Reanimated Babel plugin must be listed as the last plugin in your babel.config.js. This is required because the plugin transforms worklet functions and must run after all other Babel transforms. If the plugin is missing or not last in the list, worklets will not be compiled and the app will crash.
If you are using a babel.config.json or .babelrc instead of babel.config.js, the same rule applies. The Reanimated plugin must be the last entry in the plugins array.
Fix 2: Clean All Caches After Babel Config Change
Metro and Babel aggressively cache transformed files. If you add or change the Reanimated Babel plugin, the old cached transforms without worklet compilation may still be served. You must clear all caches for the Babel config change to take effect.
For Expo projects, also clear the Expo cache.
Fix 3: Reinstall node_modules Completely
The `bs-less-plugin` error and many other Reanimated plugin resolution errors are caused by a corrupted or incomplete node_modules. The Reanimated Babel plugin has internal dependencies that must be installed correctly. A partial npm install, interrupted yarn install, or hoisting issue can leave these internal files missing.
If the plugin/index.js file does not exist after npm install, the Reanimated package itself may be corrupted. Remove it and install it again.
Fix 4: Match Reanimated Version to React Native and Expo
Reanimated versions are tightly coupled to React Native and Expo SDK versions. Installing the latest Reanimated on an older React Native version or vice versa causes Babel plugin incompatibilities, native build failures, and runtime crashes. Always use the version that matches your setup.
Fix 5: Handle Multiple Reanimated Versions in Monorepo
In monorepos using Yarn workspaces, Turborepo, or npm workspaces, package hoisting can install multiple versions of react-native-reanimated. The Babel plugin from one version tries to transform code for a different runtime version, causing errors.
Fix 6: Rebuild Native Code After Reanimated Update
Reanimated includes native C++ and Objective-C code that must be compiled into the iOS and Android binaries. If you update Reanimated but skip the native rebuild, the JavaScript runtime expects new native APIs that do not exist in the old binary. This causes runtime crashes even when Metro bundles successfully.
Fix 7: Babel Plugin Config for Custom Worklet Directories
If you use a non-standard project structure or custom source directories, the Reanimated Babel plugin may not find your worklet files. You can pass options to the plugin to configure which files it processes.
Quick Diagnosis Checklist
- Check babel.config.js has react-native-reanimated/plugin as the LAST plugin
- Verify plugin file exists: ls node_modules/react-native-reanimated/plugin/index.js
- Check Reanimated version matches React Native version
- For Expo: run npx expo-doctor@latest to check compatibility
- Clear all caches: watchman, Metro temp files, node_modules/.cache
- Delete node_modules and reinstall if bs-less-plugin error persists
- Check for duplicate Reanimated versions in monorepo
- Rebuild native code on iOS (pod install) and Android (gradlew clean) after updates
- Runtime worklet errors with correct Babel config means stale cached bundle
- If using Expo Go: Reanimated is included, but version must match your SDK
Final Working Commands
Official-Style Error Explanation
React Native Reanimated Babel plugin errors occur when Metro bundler cannot find or execute the react-native-reanimated/plugin module during JavaScript compilation. The Reanimated Babel plugin is required to transform worklet functions at build time so they can run on the UI thread. When the plugin is missing from babel.config.js, placed in the wrong position (not last), from an incompatible version, or when its internal dependencies like bs-less-plugin cannot be resolved due to corrupted or partial node_modules installation, the build fails. Runtime errors like `worklet functions can only be used on the UI thread` or `__reanimatedWorkletInit is not a function` indicate the Babel plugin did not process the file, usually because of stale Metro cache serving pre-compiled bundles without worklet transforms. The fix is to ensure the plugin is listed last in babel.config.js, match the Reanimated version to your React Native version, clean all caches after any config change, and rebuild native code after updates.
FAQ
Why must react-native-reanimated/plugin be the last Babel plugin?
The Reanimated plugin transforms worklet functions by extracting them from the main bundle and compiling them separately for the UI thread. It must run after all other Babel transforms are complete so it sees the final version of your code. If another plugin runs after Reanimated, it may modify the already-transformed worklets and break them.
What is bs-less-plugin and why can't Metro find it?
bs-less-plugin is an internal dependency used by the Reanimated Babel plugin build system. When Metro reports it cannot resolve this module, it usually means node_modules is corrupted or partially installed. Deleting node_modules completely and running a fresh npm install resolves this in most cases.
I added the Babel plugin but still get worklet errors at runtime. Why?
Metro aggressively caches compiled JavaScript files. After adding or changing the Babel plugin, you must clear all caches: Metro cache, Babel cache in node_modules/.cache, watchman, and temp directory metro files. Then restart Metro with the --reset-cache flag. Without this, Metro serves old cached bundles that were compiled without the Reanimated plugin.
Can I use Reanimated 3 with an older React Native version?
Only within the supported version range. Reanimated 3.x requires RN 0.72 or above. Reanimated 3.10 and above requires RN 0.74 or above. Reanimated 3.16 and above requires RN 0.76 or above. Installing an incompatible combination causes Babel plugin errors, native build failures, or runtime crashes. For Expo projects, use npx expo install react-native-reanimated to get the correct version automatically.
Do I need the Babel plugin if I only use Reanimated for layout animations?
Yes. Even if you only use layout animations like entering and exiting transitions, the Babel plugin is still required. Layout animations use worklets internally, and the plugin must process them. The only Reanimated feature that works without the plugin is basic animated styles using useAnimatedStyle when not using the worklet directive, but this is limited and not recommended.
How do I fix this error in a Turborepo or Nx monorepo?
Check for duplicate Reanimated installations with find . -path */react-native-reanimated/package.json and verify only one version exists. Use resolutions in Yarn or overrides in npm to force a single version. Make sure babel.config.js in your app workspace (not the monorepo root) has the Reanimated plugin listed last. Hoisting issues can cause the Babel plugin from one version to run against the runtime from a different version.
Shahmeer Rizwan
Full-Stack Developer