Skip to content
useffect.sh
Book 30 min with a senior
Performance

Worklet

A small JavaScript function the Reanimated Babel plugin extracts to run on the UI thread, in a separate runtime.

Definition

A worklet is a short JavaScript function that can run on React Native’s UI thread, inside a JavaScript runtime separate from the app’s, instead of on the main JavaScript thread. It is the mechanism Reanimated and Gesture Handler are built on: the callback of an animation or a gesture is copied, together with the variables it captures, into that secondary runtime and called on every frame without crossing the JS thread. A function becomes a worklet through the "worklet" directive at the top of its body, or automatically when passed to a Reanimated API, thanks to the Babel plugin shipped by react-native-worklets, the package that carries this feature since Reanimated 4. The worklet replaces the old model where every animation frame needed a round trip to the JS thread, which stuttered as soon as React was busy. You meet it when writing a useAnimatedStyle, reading a Reanimated error message, or when a console.log in a gesture callback does not do what you expected.

In a real app

The rule to remember: a worklet only sees what it captured when it was created, and can only call other worklets or native functions exposed to the UI runtime. Calling an ordinary function (a setState, a navigation, a network call) from a worklet throws; you go through scheduleOnRN(fn, ...args) from react-native-worklets, which schedules the call on the JS thread (Reanimated 3’s runOnJS). The other way around, scheduleOnUI replaces runOnUI to run a worklet from the JS thread.

Typical pitfalls: a closure capturing a large object (the whole data list, say), copied into the UI runtime on every creation; a utility function imported from a file without the worklet directive, failing on first call; console.log output that seems out of order because it comes from two runtimes. The “Tried to synchronously call a non-worklet function on the UI thread” message names exactly that situation.

To confirm the plugin is active, a working useAnimatedStyle is enough; if it fails with a worklet error, it is usually babel.config.js (plugin missing or misplaced) or a Metro cache to clear. Worklets also serve outside animation, for instance to process camera frames with VisionCamera, which exposes its own worklet runtime.

Sources

All 35 glossary terms

One of these is blocking your app?

30 minutes with a senior to look at the problem in your code. Free.