3

I noticed that runOnJS is deprecated in "react-native-worklets": "0.5.1". ESLint keeps hinting me concerning this deprecation and I can't move on unless I disable eslint for the line (which is not best practice).

import { runOnJS } from 'react-native-worklets';

And this is how I use it and working with no problem:

  const handleSlideInNewPosition = useCallback(
    (newPositionsParams: {
      currentOffScreen: number;
      onScreenValue: number;
    }): void => {
      const { currentOffScreen, onScreenValue } = newPositionsParams;

      setContent({ actions, message, severity });
      latestPositionRef.current = position;

      translateY.value = withTiming(onScreenValue, {
        duration: ANIMATION_DUREATION,
        easing: Easing.out(Easing.cubic),
      });

      if (!isPersistent) {
        timerIdRef.current = setTimeout(() => {
          translateY.value = withTiming(
            currentOffScreen,
            { duration: ANIMATION_DUREATION, easing: Easing.in(Easing.cubic) },
            (isFinished) => {
              if (isFinished) {
                runOnJS(() => { // <--- JUST BOTHER THIS SCOPE
                  setMounted(false);
                  hideToaster();
                });
              }
            },
          );
        }, duration);
      }
    },
    [
      actions,
      duration,
      hideToaster,
      isPersistent,
      latestPositionRef,
      message,
      position,
      setContent,
      setMounted,
      severity,
      timerIdRef,
      translateY,
    ],
  );

But then I open the file in the node modules to read about the replacement for runOnJS. It says:

 * @param fun - A reference to a function you want to execute on the JavaScript
 *   thread from the UI thread.
 * @returns A function that accepts arguments for the function passed as the
 *   first argument.
 * @see https://docs.swmansion.com/react-native-worklets/docs/threading/runOnJS
 */
/** @deprecated Use `scheduleOnRN` instead. */
export function runOnJS<Args extends unknown[], ReturnValue>(

So I replace runOnJS with that scheduleOnRN:

import { scheduleOnRN } from 'react-native-worklets';

              ...
              if (isFinished) {
                scheduleOnRN(() => {
                  setMounted(false);
                  hideToaster();
                });
              }
              ...

That doesn't leave ESLint error hint anymore but... EVERYTIME THAT GETS INVOKED, MY APP ON ANDROID EMULATOR QUITS! However, that doesn't cause issue on web.

Even when I simply run it with empty function, it crashes the same:

import { scheduleOnRN } from 'react-native-worklets';

              ...
              if (isFinished) {
                scheduleOnRN(() => {
                });
              }
              ...

The log from adb logcat:

09-26 07:31:52.589 25933 25933 F libc : Fatal signal 11 (SIGSEGV), code 1 (SEGV_MAPERR), fault addr 0x394d28b2cca5d879 in tid 25933 (st.exp.exponent), pid 25933 (st.exp.exponent)

This is my React Native Setup relevant to this issue:

  • "react-native": "0.81.4"
  • "expo": "~54.0.10",
  • "react-native-worklets": "0.5.1"
  • "react-native-reanimated": "~4.1.0"

I run on Android emulator:

  • Expo Go 54.0.5
  • emulator -avd Pixel_9 54.0.4
  • Android Studio: Narwhal 3 Feature Drop | 2025.1.3 Build #AI-251.26094.121.2513.14007798, built on August 28, 2025 Runtime: OpenJDK 64-Bit Server VM (21.0.7 aarch64) by JetBrains OS: macOS 14.3
  • Android Debug Bridge version 1.0.41 Version 36.0.0-13206524 Running on Darwin 23.3.0 (arm64)

1 Answer 1

7

I had the same issue, but I found a way to make it work.

If I use it like this, may App (on iOS) crashes:

position.value = withTiming(-300, { duration: 100 }, (finished) => {
    if (finished) {
       scheduleOnRN(() => onDelete(item.key));  // like a callback
    }
})

But if I use it like this, it works:

position.value = withTiming(-300, { duration: 100 }, (finished) => {
    if (finished) {
        scheduleOnRN(onDelete, item.key);
    }
})

scheduleOnRN takes a function as the first param, and the follow up params are the arguments that will be passed down to that function.

:-)

howEver I dont fully trust it now, so I wrapped it in a try catch block to be sure:


 position.value = withTiming(-300, { duration: 100 }, (finished) => {
     if (finished) {
         try {
              scheduleOnRN(onDelete, item.key);
         } catch (err) {
              console.warn('could not delete item:', item.key, '- Error: ', err)
         }
     }
 })


Sign up to request clarification or add additional context in comments.

3 Comments

Thank you so much for this, it does crash on my Android if i use an anonymous function like that, and it works if i pass the function and its params separately
Wow that works! That scheduleOnRN(onDelete, item.key) really doesn't cause crash on Android and works on web too. Awesome! Thank you very much!
That scheduleOnRN(onDelete, item.key), works for me as well

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.