Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 46 additions & 24 deletions packages/docs-reanimated/docs/guides/worklets.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ sidebar_position: 1

Worklets are short-running JavaScript functions that can run on the [UI thread](/docs/fundamentals/glossary#ui-thread). Reanimated uses worklets to calculate view styles and react to events on the UI thread.

## Defining worklets

You can create your own worklets using the `'worklet';` directive at the top of a function.

```javascript
Expand All @@ -17,6 +19,8 @@ function myWorklet() {
}
```

## Workletization

The [Reanimated Babel Plugin](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-reanimated/plugin/README-dev.md#basics) looks for functions marked with the `'worklet'` directive and converts them into serializable objects. We call this process [workletization](/docs/fundamentals/glossary#to-workletize). These objects can then be copied and run over on the UI thread.

Most of the time when working with Reanimated and [Gesture Handler](https://docs.swmansion.com/react-native-gesture-handler/) the code is automatically workletized and run on the UI thread by default.
Expand All @@ -32,7 +36,7 @@ function App() {
}
```

Functions marked with `'worklet';` aren't [hoisted](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting). Besides affecting hoisting, the `'worklet';` directive has no effect on the [JavaScript thread](/docs/fundamentals/glossary#javascript-thread).
## Running worklets on the UI thread

You can use [`runOnUI`](/docs/threading/runOnUI) to manually schedule worklet execution on the UI thread:

Expand Down Expand Up @@ -60,6 +64,41 @@ function onPress() {
}
```

## Running functions from worklets

You can run functions on the JS thread from the UI thread with [`runOnJS`](/docs/threading/runOnJS). Most frequently used to call functions that aren't marked with a `'worklet';` directive (i.e. most third-party libraries) or to update the React state.

```javascript
import { router } from 'expo-router';
import { Gesture } from 'react-native-gesture-handler';

function App() {
const tap = Gesture.Tap().onEnd(() => {
// i'm a worklet too!
// highlight-next-line
runOnJS(router.back)();
});
}
```

Functions passed to `runOnJS` must be defined in the [JavaScript thread](/docs/fundamentals/glossary#javascript-thread) scope, i.e. in the component body or the global scope. This code won't work because `myFunction` is defined in the `withTiming` callback, which is only executed in the [UI thread](/docs/fundamentals/glossary#ui-thread):

```javascript
function App() {
const tap = Gesture.Tap().onEnd(() => {
// myFunction is defined on the UI thread 🚨
const myFunction = () => {};
runOnJS(myFunction)(); // 💥
});
}
```

## Hoisting

Functions marked with `'worklet';` aren't [hoisted](https://developer.mozilla.org/en-US/docs/Glossary/Hoisting). Besides affecting hoisting, the `'worklet';` directive has no effect on the [JavaScript thread](/docs/fundamentals/glossary#javascript-thread).

## Capturing closure

Worklets are [closures](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Closures). They can access variables declared outside of their own scope. Only variables referenced in the worklet body will be captured inside the worklet scope.

```javascript
Expand Down Expand Up @@ -94,6 +133,8 @@ function myWorklet() {
}
```

## Passing data to worklets

Worklets can return data within the same thread.

```javascript
Expand Down Expand Up @@ -128,32 +169,13 @@ function App() {
}
```

You can run functions on the JS thread from the UI thread with [`runOnJS`](/docs/threading/runOnJS). Most frequently used to call functions that aren't marked with a `'worklet';` directive (i.e. most third-party libraries) or to update the React state.
## Using worklets on the Web

```javascript
import { router } from 'expo-router';
import { Gesture } from 'react-native-gesture-handler';
There's no separate UI thread available on the Web. Because of that, when Reanimated runs in the browser, worklets are resolved to plain JavaScript functions.

function App() {
const tap = Gesture.Tap().onEnd(() => {
// i'm a worklet too!
// highlight-next-line
runOnJS(router.back)();
});
}
```
However, the `'worklet';` directive is still necessary on the Web, because Reanimated relies on the Babel plugin to capture dependencies inside worklet functions.

Functions passed to `runOnJS` must be defined in the [JavaScript thread](/docs/fundamentals/glossary#javascript-thread) scope, i.e. in the component body or the global scope. This code won't work because `myFunction` is defined in the `withTiming` callback, which is only executed in the [UI thread](/docs/fundamentals/glossary#ui-thread):

```javascript
function App() {
const tap = Gesture.Tap().onEnd(() => {
// myFunction is defined on the UI thread 🚨
const myFunction = () => {};
runOnJS(myFunction)(); // 💥
});
}
```
## Other worklet runtimes

Worklets can run in other runtimes than the one provided by Reanimated. For example [VisionCamera](https://github.com/mrousavy/react-native-vision-camera) and [LiveMarkdown](https://github.com/Expensify/react-native-live-markdown) create their own worklet runtimes.

Expand Down
2 changes: 2 additions & 0 deletions packages/docs-reanimated/docs/threading/runOnUI.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,8 @@ import RunOnUISrc from '!!raw-loader!@site/src/examples/RunOnUI';

- Make sure not to execute `runOnUI` on the UI thread as this will result in an error.

- In browsers there's no separate UI thread available. Because of that, on the Web, `runOnUI` behaves similarly to `requestAnimationFrame`. It creates a function that, when called, will be scheduled to run with given arguments on next animation frame.

## Platform compatibility

<PlatformCompatibility android ios web />