Expo. EAS Build. Metro bundler. Reanimated / react-native-worklets for UI-thread work. The shopper never heard of SHA-1. They just wanted a TestFlight build that existed.
EAS red. Metro dying while it hashes the worklet graph. A local expo start that looks fine because your laptop never ran the same transform. CI that cannot ship a binary. The app in production is last week's binary, which is a product decision you did not mean to make.
Worklets Bundle Mode (bundleMode: true on react-native-worklets/plugin) compiles worklets into a separate bundle. Metro then has to SHA-1 that graph. On EAS that step can fail. Expo 54 also likes eager imports. Eager imports have been enough to set globalThis._WORKLETS_BUNDLE_MODE as if you opted in, even when you did not.
I did not need Bundle Mode. I needed a build. The plugin default is false. I made that default explicit so Expo tree-shaking and eager imports could not "help."
// babel.config.js
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [['react-native-worklets/plugin', { bundleMode: false }]],
};
};If you are not using worklets at all, babel-preset-expo can take worklets: false so the plugin never loads. I still wanted Reanimated. I just did not want the extra bundle.
After the flag, clear Metro (npx expo start --clear) and rerun EAS. The SHA-1 step is allowed to be boring again. Fancy worklet packaging can wait until a build is not the blocker.
Happy coding!
Sander