mrkeyoor.com_
Tue 22 Sept 22:31 UTC
npmMobileupdated 22 Sept 2026

react-native-worklets review

React Native Worklets moves selected JavaScript functions into a UI runtime or separately created worker runtimes backed by native code. Its Babel plugin rewrites worklet functions, scheduling APIs cross runtime boundaries, and serializable or synchronizable values carry data between isolated JavaScript heaps. This is low-level infrastructure for React Native libraries that need predictable UI-thread or worker execution. It is not a Node worker package. Version 0.12 added WeakRef support in worklet runtimes, changed Bundle Mode script loading, and introduced the advanced `enableLocking` runtime option. The 0.12.1 patch extracts the UI-thread check into the native UI scheduler.

Verdict

Use react-native-worklets directly when you own a runtime-sensitive React Native library or native integration. Most app teams should consume it through Reanimated or another higher-level package, especially given the native rebuild burden and eight high audit findings in our resolved install.

We installed it

Lab card: what happened when we installed react-native-workletsScreenshot of react-native-worklets documentation
Install✓ · 18.9s280 packages on disk · 182 MB
ImportESM import fails · require() fails · CommonJS package
Browser1.3 KBgzipped (4.3 KB minified), bundled with esbuild
TypesTypeScript types bundled
Known vulns80 critical · 8 high · 0 moderate · 0 low (npm audit)

Answers from our run

Does react-native-worklets install cleanly?

Yes. In a fresh container with an empty cache, npm install react-native-worklets finished in 19 seconds, leaving 280 packages and 182 MB on disk. npm audit reported 8 known vulnerabilities.

How much does react-native-worklets add to a browser bundle?

1.3 KB gzipped (4.3 KB minified) when the whole package is bundled for the browser with esbuild. Importing only part of it is usually smaller.

Does react-native-worklets work with both ESM and CommonJS?

Neither plain import nor require succeeded in our sandbox, so it needs a bundler or extra setup.

Does react-native-worklets include TypeScript types?

Yes, type declarations ship inside the package, so no @types install is needed.

react-native-worklets or react-native-reanimated: which should you use?

react-native-reanimated: Choose it for animations, animated styles, gestures, and UI reactions without managing runtime objects directly. Use react-native-worklets directly when you own a runtime-sensitive React Native library or native integration.

When should you not use react-native-worklets?

Your goal is ordinary application animation or gesture handling. Reanimated and Gesture Handler own higher-level lifecycle and state APIs while consuming Worklets underneath.

API stability3/5The docs call the library functionally stable while its public API is still being honed, and the npm version remains below 1.0. Version 0.12 added runtime configuration around event loops, queues, and locking, while older runOnUI, runOnJS, executeOnUIRuntimeSync, and runOnRuntime names coexist with newer scheduling calls. The core idea is steady, but library authors need compatibility tests around every upgrade.
Docs4/5The dedicated site covers Expo and Community CLI setup, React Native version tables, runtime kinds, call-origin tables, copied closures, serializable and synchronizable memory, Babel behavior, Jest choices, web support, and detailed mismatch errors. Individual API pages include signatures and platform tables. The site follows the repository's main branch and can describe work headed for the next package, so check version badges against 0.12.1.
Maintenance5/5Worklets 0.12.1 was released on 2026-08-18, and the shared repository was pushed on 2026-08-24. GitHub shows 10,965 stars and 331 open issues and pull requests across the broader Reanimated monorepo. The 0.12 line added runtime and bundle-loading work, then received a native scheduler patch within a week. Compatibility data already covers React Native 0.87, which signals active coordination with the host framework.
Ecosystem5/5npm counted 6,897,958 downloads during 2026-08-17 through 2026-08-23. Worklets shares a repository and release coordination with Reanimated, and its runtime layer supports the kind of native execution used by animation, gesture, graphics, audio, and on-device inference libraries. Much of that reach is indirect: application developers usually install a package that depends on Worklets rather than calling its thread primitives themselves.

Use it if

  • You maintain a React Native native module that must schedule JavaScript on the UI runtime or a dedicated JSI runtime.
  • CPU work needs a worker runtime and its inputs and return values fit the package's serializable types.
  • The app uses React Native 0.83 through 0.87 on the New Architecture and can rebuild native binaries after upgrades.
  • You need the runtime and memory primitives beneath an animation, gesture, graphics, audio, or inference integration.
Skip it if

Setup reality

We installed react-native-worklets 0.12.1 in a fresh Node 22 Bookworm container. npm took 18.9 seconds, left 280 packages, and used 182 MB. The package has 14 direct dependencies and 4 peer dependencies, with 2704 KB unpacked. npm audit reported 8 known vulnerabilities, all high severity. TypeScript declarations are bundled. Both require() and ESM import failed under Node.js 22.23.2; the log recorded no diagnostic beyond that version.

This is a CommonJS package without an exports map. The browser check still built at 4.3 KB minified and 1.3 KB gzipped, but that does not make native worker APIs available on web. Expo projects run prebuild after installation. Community CLI projects add react-native-worklets/plugin to Babel plugins, reset Metro's cache, install iOS pods, and rebuild the application. Expo Go must use the exact Worklets version bundled with its Expo SDK.

A function marked with the worklet directive executes in another JavaScript runtime after transformation. Captured objects are serialized and copied at invocation, so later mutations on the RN runtime do not update that copy. Functions scheduled back through scheduleOnRN must have been defined in RN runtime scope. Synchronizable values provide coordinated native storage, though blocking reads or writes can stall one runtime while another holds the lock.

Version 0.12.x supports React Native 0.83 through 0.87 and is untested on Paper. Native, JavaScript, and Babel-plugin versions must match; stale transformed code can keep failing until Metro's cache is cleared and the binary is rebuilt. Jest needs the packaged mock or web resolver. Review all eight high audit paths in the actual lockfile before release, because the lab finding covers the resolved tree rather than proving which direct package owns each advisory.

Patterns

Enable worklet transformation configure-babel-plugin

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

Community CLI projects add this plugin, clear Metro's cache, and rebuild native code. Expo starter templates from SDK 54 include it.

Queue work on the UI runtime schedule-ui-task

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

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

scheduleOnUI(readFrame, 'drag');

scheduleOnUI returns no value and runs asynchronously. On web it uses requestAnimationFrame.

Receive a value from the UI runtime await-ui-result

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

const distance = await runOnUIAsync(
  (start: number, end: number) => {
    'worklet';
    return end - start;
  },
  24,
  96
);

Pass the function reference and arguments separately. Calling the function before passing it executes on the current runtime.

Read a tiny UI value synchronously run-ui-synchronously

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

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

The caller blocks until the UI runtime returns. Keep the callback short and prefer runOnUIAsync when immediate ordering is unnecessary.

Create a named worker runtime create-worker-runtime

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

const worker = createWorkletRuntime({
  name: 'image-math',
  initializer: () => {
    'worklet';
    console.log('image-math initialized');
  },
  enableEventLoop: true,
  enableLocking: true,
});

Worker runtimes are native-only. The initializer runs synchronously, and disabling locking requires disabling the event loop too.

Send fire-and-forget work to a worker schedule-worker-task

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

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

scheduleOnRuntime returns no result. Its arguments cross into another runtime as serializable values.

Await computation on a worker runtime await-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 native-only call returns a Promise. A thrown worklet error rejects that Promise.

Schedule a React state update return-to-rn-runtime

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

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

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

acceptProgress must be defined in RN runtime scope. A function created inside the UI callback cannot be scheduled back this way.

Coordinate a small value across runtimes share-coordinated-value

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

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

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

Synchronizable access is imperative rather than reactive. Blocking methods can wait for another runtime that holds the native lock.

Branch on the active runtime detect-current-runtime

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

function whereAmI() {
  'worklet';
  return getRuntimeKind() === RuntimeKind.UI
    ? 'ui'
    : 'another-runtime';
}

Use the enum or isUIRuntime-style helpers instead of relying on internal global variables.

Verify that Babel transformed a function check-worklet-transformation

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

function calculate(value: number) {
  'worklet';
  return value * 2;
}

console.log(isWorkletFunction(calculate));

A false result in the built app usually points to Babel configuration, stale transformed code, or a missing Metro cache reset.

Use the packaged TypeScript mock mock-native-runtime-in-jest

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

JavaScript builds use `react-native-worklets/lib/module/mock`. The documented web alternative sets `react-native-worklets/jest/resolver` in Jest config.

Alternatives

PackageRegistryPick it when
react-native-reanimatednpmChoose it for animations, animated styles, gestures, and UI reactions without managing runtime objects directly.
react-native-worklets-corenpmConsider it when a native library already targets Margelo's worklet-core conventions and its React Native compatibility fits the project.
react-native-threadsnpmConsider it for an older app built around long-lived secondary JS bundles and message passing rather than workletized functions.

More mobile guides

react-native · react-native-safe-area-context · expo · react-native-reanimated · react-native-svg · @react-native-async-storage/async-storage · the whole shelf →

How this guide is made: grounded in the library's documentation, release notes, changelog, and issue history, on a fixed rubric — not a hands-on install of every release. The 50 most-downloaded entries are additionally install-verified in clean containers. Corrections: contact the desk.