mrkeyoor.com_
Sat 08 Aug 20:58 UTC
npmMobileupdated 08 Aug 2026

react-native-worklets

React Native Worklets is the native runtime layer that moves selected JavaScript functions onto the UI runtime or separate worker runtimes. A Babel transform turns functions marked with a 'worklet' directive into transferable code, while scheduling APIs move serializable arguments and results between runtimes. It is infrastructure for animation, gesture, graphics, and compute-heavy React Native libraries, not a general replacement for promises, Web Workers, or ordinary application state.

Verdict

Use Worklets directly when you are building the runtime-sensitive layer of a React Native library. Most application teams should install the higher-level library that already depends on it and avoid owning the native rebuild, compatibility, and cross-runtime memory rules themselves.

API stability3/5The current 0.11.3 API is explicitly pre-1.0, and the official getting-started page says the library is in a transitional period while the API is being honed. Several familiar calls, including runOnUI and runOnJS, are already deprecated for removal in the next major release in favor of scheduleOnUI and scheduleOnRN. Functional behavior is described as production-ready, but names and call shapes still require migration attention.
Docs5/5The dedicated documentation covers installation for Expo and Community CLI, React Native compatibility, runtime kinds, closure copying, serializable and synchronizable memory, call-origin tables, native versus Web support, Jest setup, and specific version-mismatch errors. Individual API pages include signatures, examples, remarks, and platform tables, which is unusually complete for a native package whose public version is still below 1.0.
Maintenance5/5The shared Software Mansion repository was pushed on 2026-08-08, Worklets 0.11.3 was released on 2026-07-24, and the README lists nightly package publishing, Expo DevClient builds, runtime tests, compatibility checks, and URL validation. The repository has 379 open issues and pull requests, a meaningful support load, but the fresh release and broad automated matrix show active engineering rather than a dormant native bridge.
Ecosystem5/5The package recorded 6,066,871 npm downloads for the last complete week, and its repository has 10,949 stars. More importantly, the project README identifies Worklets as the execution foundation used by prominent React Native libraries including Reanimated, Gesture Handler, Skia, Screens, SVG, Live Markdown, Audio API, and ExecuTorch. That reach is strong, although most developers consume it indirectly through those higher-level packages.

Use it if

  • You are building a React Native library that must run small pieces of JavaScript on the UI runtime without waiting for the RN runtime
  • You need a separate native worker runtime for CPU work and can keep the worklet inputs and outputs serializable
  • You already use the New Architecture and a supported recent React Native release
  • You need the same runtime foundation used by Reanimated, Gesture Handler, or Skia but are writing your own integration
Skip it if

Setup reality

Installation changes native and JavaScript build layers. Expo users install the package and run npx expo prebuild, which creates or updates ios and android projects; a normal Expo Go session must use exactly the Worklets version bundled with that Expo SDK. React Native Community CLI users must add 'react-native-worklets/plugin' to the plugins array in babel.config.js, rebuild the native app, run pod install on iOS, and clear Metro's cache. Forgetting any one of those steps can produce 'Failed to create a worklet' or a mismatch among the JavaScript, Babel plugin, C++, and native versions. The published peer range for 0.11.3 is React Native 0.83 through 0.86 and the docs say Paper is not tested. Worklet closures are not ordinary closures once code crosses a runtime: captured data is serialized and copied, later mutations do not appear automatically, globals belong to each runtime, and functions sent back to the RN runtime must have been defined in RN scope. Testing also needs an explicit Jest mock or the package's Web resolver. The API is still pre-1.0 and the getting-started page calls it a transitional period, so avoid deprecated runOnUI and runOnJS in new code; scheduleOnUI and scheduleOnRN are their replacements.

Patterns

Enable worklet transformation in Community CLIconfigure-babel

module.exports = {
  presets: ['module:@react-native/babel-preset'],
  plugins: ['react-native-worklets/plugin'],
};

Put the entry in plugins, rebuild the native app, and reset Metro's cache. Expo SDK 54 and later starter templates include the plugin, but Community CLI projects must add it themselves.

Schedule a function on the UI runtimeschedule-ui-work

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

function reportFrame(label: string) {
  'worklet';
  console.log(label, performance.now());
}

scheduleOnUI(reportFrame, 'frame');

scheduleOnUI is asynchronous and returns no value. On Web it schedules with requestAnimationFrame rather than moving work to a separate UI thread.

Await a serializable result from the UI runtimeawait-ui-result

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

const width = await runOnUIAsync((left: number, right: number) => {
  'worklet';
  return right - left;
}, 12, 84);

Pass the function and its arguments separately. Calling the function before passing it runs it on the wrong runtime, and rejected worklet errors reject the returned promise.

Run a small synchronous UI queryread-ui-synchronously

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

const runtimeTime = runOnUISync(() => {
  'worklet';
  return performance.now();
});

This blocks the caller until the UI runtime returns a serializable value. Keep the callback tiny and prefer asynchronous scheduling when an immediate answer is unnecessary.

Create and initialize a worker runtimecreate-worker-runtime

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

const worker = createWorkletRuntime({
  name: 'image-math',
  initializer: () => {
    'worklet';
    globalThis.workerLabel = 'image-math';
  },
});

Worker runtimes are native-only. Each runtime has its own globals, and the initializer runs synchronously as the runtime is created.

Fire and forget work on a worker runtimeschedule-worker-task

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

scheduleOnRuntime(worker, (values: number[]) => {
  'worklet';
  console.log(values.reduce((sum, value) => sum + value, 0));
}, [4, 8, 15, 16, 23, 42]);

The work is queued and no result comes back. Inputs are serialized across runtimes, so do not expect later mutations of the original array to be visible.

Run CPU work and await its resultawait-worker-result

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

const total = await runOnRuntimeAsync(worker, (values: number[]) => {
  'worklet';
  return values.reduce((sum, value) => sum + value, 0);
}, [10, 20, 30]);

This API is native-only and must be called from the RN runtime. Errors thrown by the worklet reject the promise.

Get an immediate result from a worker runtimerun-worker-synchronously

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

const answer = runOnRuntimeSync(worker, (a: number, b: number) => {
  'worklet';
  return a * b;
}, 6, 7);

The call blocks the RN runtime and can preempt the worker runtime. Use it only for short operations where synchronous ordering is required.

Update React state from a workletreturn-to-rn-runtime

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

const acceptResult = (value: number) => setProgress(value);

scheduleOnUI(() => {
  'worklet';
  scheduleOnRN(acceptResult, 100);
});

The function passed to scheduleOnRN must be defined in RN runtime scope. Defining it inside the UI callback creates a UI-runtime function that cannot be scheduled back this way.

Share a small value between runtimesshare-pollable-state

import { createSynchronizable, scheduleOnUI } from 'react-native-worklets';

const status = createSynchronizable('idle');
status.setBlocking('working');

scheduleOnUI(() => {
  'worklet';
  console.log(status.getBlocking());
});

Synchronizable values are copied on every access and are not reactive. getBlocking and setBlocking can wait on another thread, while getDirty may return stale data.

Choose behavior by current runtimebranch-by-runtime

import { getRuntimeKind, RuntimeKind, scheduleOnRN } from 'react-native-worklets';

function logMessage(message: string) {
  'worklet';
  if (getRuntimeKind() === RuntimeKind.ReactNative) {
    console.log(message);
  } else {
    scheduleOnRN(console.log, message);
  }
}

getRuntimeKind replaces the deprecated _WORKLET global. Prefer the enum or isRNRuntime-style helpers over reading globalThis.__RUNTIME_KIND directly.

Use the packaged Jest mockmock-in-jest

jest.mock('react-native-worklets', () =>
  require('react-native-worklets/src/mock')
);

This path is the documented TypeScript setup. JavaScript builds use react-native-worklets/lib/module/mock, or set resolver to react-native-worklets/jest/resolver to exercise the Web implementation.

Alternatives

PackageRegistryPick it when
react-native-reanimatednpmChoose it for application animation and UI reactions instead of managing runtimes directly
react-native-threadsnpmChoose it when you want long-lived React Native worker threads with message passing rather than workletized functions
react-native-multithreadingnpmConsider it for an older worklet-style threading API when its React Native compatibility matches an existing app