diff --git a/.husky/pre-commit b/.husky/pre-commit
index 875248389de6..7da275d28d84 100755
--- a/.husky/pre-commit
+++ b/.husky/pre-commit
@@ -65,13 +65,13 @@ for DOCS in docs-reanimated docs-worklets; do
check_and_lint_docs "$STAGED_FILES" "$DOCS_PATH" "$DOCS"
done
-# This automatically builds Reanimated Babel plugin JavaScript files if their
+# This automatically builds Worklets Babel plugin JavaScript files if their
# TypeScript counterparts were changed. It also adds the output file to the commit
# if the built file differs from currently staged one.
-print "Checking for changes in Reanimated Babel plugin source files..."
+print "Checking for changes in Worklets Babel plugin source files..."
PLUGIN_PATH="packages/react-native-worklets/plugin"
if echo "$STAGED_FILES" | grep -E "$PLUGIN_PATH" >/dev/null; then
- print "Changes spotted. Building Reanimated Babel plugin files..."
+ print "Changes spotted. Building Worklets Babel plugin files..."
yarn workspace babel-plugin-worklets build
diff --git a/apps/fabric-example/babel.config.js b/apps/fabric-example/babel.config.js
index 259ed1ad84b1..3c9372b6ae20 100644
--- a/apps/fabric-example/babel.config.js
+++ b/apps/fabric-example/babel.config.js
@@ -1,14 +1,14 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {
+ // Uncomment the next line to enable bundle mode.
+ // bundleMode: true,
+};
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: ['module:@react-native/babel-preset'],
plugins: [
- [
- 'react-native-worklets/plugin',
- {
- // Uncomment the next line to enable bundle mode.
- // bundleMode: true,
- },
- ],
+ ['react-native-worklets/plugin', workletOptions],
[
'module-resolver',
{
diff --git a/apps/macos-example/babel.config.js b/apps/macos-example/babel.config.js
index 40ececb9687f..9513f3679626 100644
--- a/apps/macos-example/babel.config.js
+++ b/apps/macos-example/babel.config.js
@@ -1,3 +1,6 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {};
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: ['module:@react-native/babel-preset'],
@@ -12,6 +15,6 @@ module.exports = {
extensions: ['.js', '.jsx', '.ts', '.tsx'],
},
],
- 'react-native-worklets/plugin',
+ ['react-native-worklets/plugin', workletOptions],
],
};
diff --git a/apps/next-example/babel.config.js b/apps/next-example/babel.config.js
index 3f3cee47fad3..b3a9506d3c90 100644
--- a/apps/next-example/babel.config.js
+++ b/apps/next-example/babel.config.js
@@ -1,3 +1,6 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {};
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: ['next/babel'],
@@ -13,6 +16,6 @@ module.exports = {
},
},
],
- 'react-native-worklets/plugin',
+ ['react-native-worklets/plugin', workletOptions],
],
};
diff --git a/apps/tvos-example/babel.config.js b/apps/tvos-example/babel.config.js
index 26d64e7bb036..a070712960f2 100644
--- a/apps/tvos-example/babel.config.js
+++ b/apps/tvos-example/babel.config.js
@@ -1,5 +1,8 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {};
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: ['module:@react-native/babel-preset'],
- plugins: ['react-native-worklets/plugin'],
+ plugins: [['react-native-worklets/plugin', workletOptions]],
};
diff --git a/apps/web-example/babel.config.js b/apps/web-example/babel.config.js
index 85157f38da73..ce316b1d941e 100644
--- a/apps/web-example/babel.config.js
+++ b/apps/web-example/babel.config.js
@@ -1,3 +1,6 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {};
+
/** @type {import('@babel/core').ConfigFunction} */
module.exports = function (api) {
const plugins = [
@@ -18,7 +21,7 @@ module.exports = function (api) {
if (disableBabelPlugin) {
console.log('Starting Web example without Babel plugin.');
} else {
- plugins.push('react-native-worklets/plugin');
+ plugins.push(['react-native-worklets/plugin', workletOptions]);
}
return {
diff --git a/docs/docs-reanimated/docs/fundamentals/getting-started.mdx b/docs/docs-reanimated/docs/fundamentals/getting-started.mdx
index 5aff4e5caee5..a5e9a9d954de 100644
--- a/docs/docs-reanimated/docs/fundamentals/getting-started.mdx
+++ b/docs/docs-reanimated/docs/fundamentals/getting-started.mdx
@@ -49,17 +49,15 @@ Install `react-native-reanimated` and `react-native-worklets` packages from npm:
This library requires an installation of the `react-native-worklets` dependency. It was separated from `react-native-reanimated` for better modularity and must be installed separately.
+You can read more about Worklets in the [Worklets documentation](https://docs.swmansion.com/react-native-worklets/).
+
{/* TODO - add information about the necessity to specify a proper version of the library compatible with reanimated */}
- ```bash
- npm install react-native-worklets
- ```
+ ```bash npm install react-native-worklets ```
- ```bash
- yarn add react-native-worklets
- ```
+ ```bash yarn add react-native-worklets ```
@@ -69,14 +67,10 @@ Run prebuild to update the native code in the `ios` and `android` directories.
- ```bash
- npx expo prebuild
- ```
+ ```bash npx expo prebuild ```
- ```bash
- yarn expo prebuild
- ```
+ ```bash yarn expo prebuild ```
@@ -87,13 +81,18 @@ And that's it! Reanimated 4 is now configured in your Expo project.
When using [React Native Community CLI](https://github.com/react-native-community/cli), you also need to manually add the `react-native-worklets/plugin` plugin to your `babel.config.js`.
```js {7}
+ /** @type {import('react-native-worklets/plugin').PluginOptions} */
+ const workletsPluginOptions = {
+ // Your custom options.
+ }
+
module.exports = {
presets: [
... // don't add it here :)
],
plugins: [
...
- 'react-native-worklets/plugin',
+ ['react-native-worklets/plugin', workletsPluginOptions],
],
};
```
@@ -107,11 +106,11 @@ When using [React Native Community CLI](https://github.com/react-native-communit
Why do I need this?
-In short, the Reanimated babel plugin automatically converts special JavaScript functions (called [worklets](/docs/fundamentals/glossary#worklet)) to allow them to be passed and run on the UI thread.
+In short, the Worklets Babel plugin automatically converts special JavaScript functions (called [worklets](/docs/fundamentals/glossary#worklet)) to allow them to be passed and run on the UI thread.
-Since [Expo SDK 50](https://expo.dev/changelog/2024/01-18-sdk-50), the Expo starter template includes the Reanimated babel plugin by default.
+Since [Expo SDK 50](https://expo.dev/changelog/2024/01-18-sdk-50), the Expo starter template includes the Worklets Babel plugin by default.
-To learn more about the plugin head onto to [Reanimated babel plugin](/docs/fundamentals/glossary#reanimated-babel-plugin) section.
+To learn more about the plugin head onto to [Worklets Babel plugin docs page](https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/about).
@@ -119,14 +118,10 @@ To learn more about the plugin head onto to [Reanimated babel plugin](/docs/fund
- ```bash
- npm start -- --reset-cache
- ```
+ ```bash npm start -- --reset-cache ```
- ```bash
- yarn start --reset-cache
- ```
+ ```bash yarn start --reset-cache ```
@@ -150,18 +145,19 @@ To use Reanimated on the web all you need to do is to install and add [`@babel/p
- ```bash
- npm install @babel/plugin-proposal-export-namespace-from
- ```
+ ```bash npm install @babel/plugin-proposal-export-namespace-from ```
- ```bash
- yarn add @babel/plugin-proposal-export-namespace-from
- ```
+ ```bash yarn add @babel/plugin-proposal-export-namespace-from ```
```js {7}
+ /** @type {import('react-native-worklets/plugin').PluginOptions} */
+ const workletsPluginOptions = {
+ // Your custom options.
+ }
+
module.exports = {
presets: [
... // don't add it here :)
@@ -169,7 +165,7 @@ To use Reanimated on the web all you need to do is to install and add [`@babel/p
plugins: [
...
'@babel/plugin-proposal-export-namespace-from',
- 'react-native-worklets/plugin',
+ ['react-native-worklets/plugin', workletsPluginOptions],
],
};
```
diff --git a/docs/docs-reanimated/docs/fundamentals/glossary.mdx b/docs/docs-reanimated/docs/fundamentals/glossary.mdx
index 69ca7adff61b..64277a38ff7d 100644
--- a/docs/docs-reanimated/docs/fundamentals/glossary.mdx
+++ b/docs/docs-reanimated/docs/fundamentals/glossary.mdx
@@ -170,7 +170,7 @@ function onPress() {
To convert a JavaScript function into a serializable object which can be copied and run over on [UI thread](/docs/fundamentals/glossary#ui-thread).
-Functions marked with `"worklet";` directive are automatically picked up and workletized by the Reanimated Babel plugin.
+Functions marked with `"worklet"` directive are automatically picked up and workletized by the Worklets Babel plugin.
## JavaScript thread
@@ -184,8 +184,8 @@ UI thread is responsible for handling user interface updates. Also known as Main
You can learn more about it by reading the [Threading model](https://reactnative.dev/architecture/threading-model) article in the official React Native docs.
-## Reanimated Babel plugin
+## Worklets Babel plugin
The plugin performs automatic [workletization](/docs/fundamentals/glossary#to-workletize) of certain functions used with Reanimated to reduce the amount of boilerplate code.
-You can learn the details by reading the [Reanimated Babel plugin README](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/plugin/README-dev.md).
+You can learn the details by reading the [Worklets docs](https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/about).
diff --git a/docs/docs-reanimated/docs/guides/debugging-worklets.mdx b/docs/docs-reanimated/docs/guides/debugging-worklets.mdx
index 38c5b4fcfde5..f6e1df753978 100644
--- a/docs/docs-reanimated/docs/guides/debugging-worklets.mdx
+++ b/docs/docs-reanimated/docs/guides/debugging-worklets.mdx
@@ -181,7 +181,7 @@ _Warnings about mismatched patch versions can be safely ignored if the patch was
You may choose either `Reanimated Runtime` or `Reanimated Runtime experimental
(Improved Chrome Reloads)`, but we recommend the latter.
-_Debugging relies on source maps that are generated by the Reanimated Babel plugin, so you
+_Debugging relies on source maps that are generated by the Worklets Babel plugin, so you
might have to run `yarn start --reset-cache` for those changes to take effect.
In case it still doesn't work after that please reinstall the app and reset metro
cache once again._
@@ -247,7 +247,7 @@ _Warnings about mismatched patch versions can be safely ignored if the patch was

-_Debugging relies on source maps that are generated by the Reanimated Babel plugin, so you
+_Debugging relies on source maps that are generated by the Worklets Babel plugin, so you
might have to run `yarn start --reset-cache` for those changes to take effect.
In case it still doesn't work after that please reinstall the app and reset metro
cache once again._
diff --git a/docs/docs-reanimated/docs/guides/troubleshooting.mdx b/docs/docs-reanimated/docs/guides/troubleshooting.mdx
index 7e9a4d59d869..4c55b18734e8 100644
--- a/docs/docs-reanimated/docs/guides/troubleshooting.mdx
+++ b/docs/docs-reanimated/docs/guides/troubleshooting.mdx
@@ -8,20 +8,21 @@ sidebar_label: Troubleshooting
## Initialization issues
-Reanimated has four core components that compose its code:
+Reanimated has three core components that compose its code:
- C++,
- Java,
-- JavaScript,
-- Reanimated Babel plugin.
+- JavaScript.
+
+It also depends on React Native Worklets and its Worklets Babel plugin.
All of them are supposed to work correctly only within the same minor version. Therefore, having any of those pieces in your code - directly or indirectly - separate from `react-native-reanimated`, especially having any code transpiled with a different version of the aforementioned plugin will result in undefined behavior and errors.
### Failed to create a worklet
-**Problem:** This usually happens when Reanimated is not properly installed, e.g. forgetting to include the Reanimated Babel plugin in `babel.config.js`.
+**Problem:** This usually happens when Reanimated is not properly installed, e.g. forgetting to include the Worklets Babel plugin in `babel.config.js`.
-**Solution:** See installation docs at https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#step-2-add-reanimateds-babel-plugin for more information.
+**Solution:** See installation docs at https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/getting-started/#react-native-community-cli for more information.
### Native part of Reanimated doesn't seem to be initialized
@@ -63,7 +64,7 @@ See [Couldn't determine the version of the native part of Reanimated](#couldnt-d
### Mismatch between C++ code version and JavaScript code version
-See [Mismatch between JavaScript part and native part of Reanimated](#mismatch-between-javascript-part-and-native-part-of-reanimated) and [Mismatch between JavaScript code version and Reanimated Babel plugin version](https://docs.swmansion.com/react-native-worklets/docs/guides/troubleshooting#mismatch-between-javascript-code-version-and-worklets-babel-plugin-version).
+See [Mismatch between JavaScript part and native part of Reanimated](#mismatch-between-javascript-part-and-native-part-of-reanimated) and [Mismatch between JavaScript code version and Worklets Babel plugin version](https://docs.swmansion.com/react-native-worklets/docs/guides/troubleshooting#mismatch-between-javascript-code-version-and-worklets-babel-plugin-version).
### C++ side failed to resolve Java code version
diff --git a/docs/docs-reanimated/docs/guides/worklets.mdx b/docs/docs-reanimated/docs/guides/worklets.mdx
index 7de176749928..28b300f0dde6 100644
--- a/docs/docs-reanimated/docs/guides/worklets.mdx
+++ b/docs/docs-reanimated/docs/guides/worklets.mdx
@@ -6,11 +6,11 @@ sidebar_position: 1
# Worklets
-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.
+Worklet is a short-running JavaScript function that can be moved and executed across different Javascript Runtimes. 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.
+You can create your own worklets using the `'worklet'` directive at the top of a function.
```javascript
function myWorklet() {
@@ -21,9 +21,9 @@ function myWorklet() {
## Workletization
-The [Reanimated Babel Plugin](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/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.
+The [Worklets Babel plugin](https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/about) 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.
+Most of the time when working with [Reanimated](https://docs.swmansion.com/react-native-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.
```javascript
import { useAnimatedStyle } from 'react-native-reanimated';
@@ -36,9 +36,9 @@ function App() {
}
```
-## Running worklets on the UI thread
+## Running worklets on the UI Runtime (UI Thread)
-You can use [`runOnUI`](https://docs.swmansion.com/react-native-worklets/docs/threading/runOnUI) to manually schedule worklet execution on the UI thread:
+You can use [`scheduleOnUI`](https://docs.swmansion.com/react-native-worklets/docs/threading/scheduleOnUI) to manually schedule worklet execution on the UI Runtime:
```javascript
function myWorklet() {
@@ -47,7 +47,7 @@ function myWorklet() {
}
function onPress() {
- runOnUI(myWorklet)();
+ scheduleOnUI(myWorklet);
}
```
@@ -60,13 +60,13 @@ function myWorklet(greeting) {
}
function onPress() {
- runOnUI(myWorklet)('Howdy');
+ scheduleOnUI(myWorklet, 'Howdy');
}
```
## Running functions from worklets
-You can run functions on the JS thread from the UI thread with [`runOnJS`](https://docs.swmansion.com/react-native-worklets/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.
+You can run functions on the RN Runtime (JS thread) from the UI Runtime (UI thread) with [`scheduleOnRN`](https://docs.swmansion.com/react-native-worklets/docs/threading/scheduleOnRN). 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';
@@ -76,26 +76,26 @@ function App() {
const tap = Gesture.Tap().onEnd(() => {
// i'm a worklet too!
// highlight-next-line
- runOnJS(router.back)();
+ scheduleOnRN(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):
+Functions passed to `scheduleOnRN` 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 Runtime](/docs/fundamentals/glossary#ui-runtime):
```javascript
function App() {
const tap = Gesture.Tap().onEnd(() => {
- // myFunction is defined on the UI thread 🚨
+ // myFunction is defined on the UI runtime 🚨
const myFunction = () => {};
- runOnJS(myFunction)(); // 💥
+ scheduleOnRN(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).
+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 [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime).
## Capturing closure
@@ -171,12 +171,12 @@ function App() {
## Using worklets on the Web
-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.
+There's no separate UI thread available on the Web. Because of that, when Worklets run in the browser, worklets are resolved to plain JavaScript functions.
-However, the `'worklet';` directive is still necessary on the Web, because Reanimated relies on the Babel plugin to capture dependencies inside worklet functions.
+However, the `'worklet'` directive is still necessary on the Web, because Reanimated relies on the Worklets Babel plugin to capture dependencies inside worklet functions.
## 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.
+Worklets can run in other runtimes than the one provided by React Native Worklets. 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.
You can create your own worklet runtimes with [`createWorkletRuntime`](https://docs.swmansion.com/react-native-worklets/docs/threading/createWorkletRuntime) function.
diff --git a/docs/docs-reanimated/docs/reanimated-babel-plugin/about.md b/docs/docs-reanimated/docs/reanimated-babel-plugin/about.md
index d5c38124fa5c..8304887b34b3 100644
--- a/docs/docs-reanimated/docs/reanimated-babel-plugin/about.md
+++ b/docs/docs-reanimated/docs/reanimated-babel-plugin/about.md
@@ -6,293 +6,13 @@ sidebar_label: 'About'
# Reanimated Babel Plugin
-## What is Reanimated Babel Plugin?
+Reanimated Babel plugin was moved to `react-native-worklets` and renamed to [Worklets Babel plugin](https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/about/). Please make sure to import the plugin from `react-native-worklets/plugin` in your `babel.config.js`.
-The Reanimated Babel Plugin transforms your code so that it can run on the [UI thread](/docs/fundamentals/glossary#ui-thread). It looks for functions marked with a `'worklet';` directive and converts them into serializable objects. We call this process [workletization](/docs/fundamentals/glossary#to-workletize).
-
-In short, a worklet is:
-
-- A function that contains a `'worklet'` directive at its very top, i.e.:
-
-```ts
-function foo() {
- 'worklet';
- console.log('Hello from worklet');
-}
-```
-
-- A function that is _autoworkletizable_, i.e.:
-
-```ts
-useAnimatedStyle(() => {
- // This function will be ran on the UI thread,
- // hence it's in a workletizable context and will be
- // autoworkletized. You don't need to add the 'worklet' directive here.
- return {
- width: 100,
- };
-});
-```
-
-## What can be a worklet?
-
-### JavaScript terms
-
-Reanimated Babel Plugin supports the following terms as worklets:
-
-#### Function Declarations
-
-```ts
-function foo() {
- 'worklet';
- console.log('Hello from FunctionDeclaration');
-}
-```
-
-#### Function Expressions
-
-```ts
-const foo = function () {
- 'worklet';
- console.log('Hello from FunctionExpression');
-};
-```
-
-#### Arrow Function Expressions
-
-```ts
-const foo = () => {
- 'worklet';
- console.log('Hello from ArrowFunctionExpression');
-};
-```
-
-#### Object Methods
-
-```ts
-const obj = {
- foo() {
- 'worklet';
- console.log('Hello from ObjectMethod');
- },
-};
-```
-
-### Reanimated terms
-
-#### [Experimental] Worklet Context Objects
-
-_Object methods_ called on UI thread lose their `this` binding.
-
-```ts
-const obj = {
- foo: 1,
- bar() {
- 'worklet';
- console.log(this.foo); // undefined - the binding was lost.
- },
-};
-```
-
-**Worklet Context Objects** are special terms that preserve that binding. Don't mistake them for objects created with `useSharedValue`. All changes to Worklet Context Objects on the UI thread are visible only on the UI thread. The same applies to the JS thread.
-
-```ts
-const obj = {
- __workletContextObject: true,
- foo: 1,
- bar() {
- console.log(this.foo);
- },
-};
-
-obj.foo = 2;
-obj.bar(); // Logs 2
-runOnUI(() => obj.bar())(); // Logs 1
-
-runOnUI(() => (obj.foo = 3))();
-obj.bar(); // Logs 2
-runOnUI(() => obj.bar())(); // Logs 3
-```
-
-`__workletContextObject` is a special property that marks an object as a Worklet Context Object. It's value doesn't matter, but it's a good practice to use `true` as a value. `'worklet'` directive in methods will be ignored if the object has this property.
-
-```ts
-const workletContextObject = {
- __workletContextObject: true,
- message: 'Hello from WorkletContextObject',
- foo() {
- console.log(this.message);
- },
-};
-```
-
-#### [Experimental] Worklet Classes
-
-[Hermes](https://github.com/facebook/hermes), the JavaScript engine used by React Native, doesn't support classes. Class syntax requires [polyfilling](https://en.wikipedia.org/wiki/Polyfill_%28programming%29) before it can be used, which is problematic for the UI thread. To work around this, we coined the term of **Worklet Classes**. Worklet classes can be instantiated on the UI thread.
-
-`__workletClass` is a special property that marks a class as a Worklet Class. It's value doesn't matter, but it's a good practice to use `true` as a value. `'worklet'` directive in methods will be ignored if the class has this property.
-
-```ts
-class Clazz {
- __workletClass = true;
- message = 'Hello from WorkletClass';
- foo() {
- console.log(this.message);
- }
-}
-
-runOnUI(() => new Clazz().foo())(); // Logs 'Hello from WorkletClass'
-```
-
-**Pitfalls:**
-
-- Worklet Classes don't support inheritance.
-- Worklet Classes don't support static methods and properties.
-- Class instances cannot be shared between JS and UI threads.
-
-## Autoworkletization
-
-To reduce boilerplate code and provide a safer API, Reanimated Babel Plugin detects automatically whether a function should be workletized. Thanks to that, you don't need to add the `'worklet'` directive to your callbacks:
-
-```ts
-const style = useAnimatedStyle(() => {
- // You don't need to add the 'worklet' directive here,
- // since plugin detects this callback as autoworkletizable.
- return {
- width: 100,
- };
-});
-```
-
-This isn't limited to `useAnimatedStyle` hook - Reanimated Babel Plugin autoworkletizes all callbacks for the API of Reanimated. The whole list can be found in the [plugin source code](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/plugin/src/autoworkletization.ts).
-
-Keep in mind that in more advanced use cases, you might still need to manually mark a function as a worklet.
-
-### Referencing worklets
-
-You can define worklets **before** they are used and the plugin will autoworkletize them too:
-
-```ts
-function foo() {
- // You don't need to add
- // the 'worklet' directive here.
- return { width: 100 };
-}
-
-// You don't need to define an inline function here,
-// a reference is enough.
-const style = useAnimatedStyle(foo);
-```
-
-### Objects aggregating worklets
-
-In some APIs, like `useAnimatedScrollHandler` you can pass an object that contains worklets instead of a function:
-
-```ts
-const handlerObject = {
- // You don't need to mark these methods as worklets.
- onBeginDrag() {
- console.log('Dragging...');
- },
- onScroll() {
- console.log('Scrolling...');
- },
-};
-
-const handler = useAnimatedScrollHandler(handlerObject);
-```
-
-### [Experimental] Workletizing whole files
-
-You can mark a file as a workletizable file by adding the `'worklet'` directive to the top of the file.
-
-This will workletize all _top-level_ [JavaScript terms](#javascript-terms) and [Reanimated terms](#reanimated-terms) automatically. It can come in handy for files that contain multiple worklets.
-
-```ts
-// file.ts
-'worklet';
-
-function foo() {
- // Function 'foo' will be autoworkletized.
- return { width: 100 };
-}
-
-function bar() {
- // Function 'bar' will be autoworkletized.
- function foobar() {
- // Function 'foobar' won't since it's not defined in top-level scope.
- console.log("I'm not a worklet");
- }
- return { width: 100 };
-}
-```
-
-## Limits of autoworkletization
-
-The plugin cannot infer whether a function is autoworkletizable or not in some contexts.
-
-### Imports
-
-When importing a function from another file or a module and using it as a worklet, you must manually add the `'worklet'` directive to the function:
-
-```ts
-// foo.ts
-import { bar } from './bar';
-// ...
-const style = useAnimatedStyle(bar);
-
-// bar.ts
-export function bar() {
- 'worklet'; // Won't work without it.
- return {
- width: 100,
- };
-}
-```
-
-### Custom hooks
-
-Currently Reanimated hasn't exposed APIs that would allow you to register your custom hooks for callback workletization. This however, might change in the future.
-
-### Expressions
-
-A function won't get automatically workletized when it's a result of an expression. You have to add the `'worklet';` directive to make it work:
-
-```ts
-const foo = someCondition
- ? () => {
- 'worklet'; // Won't work without it.
- return { width: 100 };
- }
- : () => {
- 'worklet'; // Won't work without it.
- return { width: 200 };
- };
-
-const style = useAnimatedStyle(foo);
+```diff
+plugins: [
+- 'react-native-reanimated/plugin',
++ 'react-native-worklets/plugin',
+],
```
-In such cases we recommend either handling the conditional logic in the worklet itself or refactoring your code to eliminate the need for conditional worklets.
-
-## Pitfalls
-
-There are some patterns that won't work with the plugin.
-
-### Hoisting worklets
-
-Worklets aren't hoisted. This means that you can't use worklets before they are defined:
-
-```ts
-// The following line crashes,
-// even though 'foo' is marked as a worklet.
-const style = useAnimatedStyle(foo);
-
-function foo() {
- 'worklet';
- return { width: 100 };
-}
-```
-
-## Notes
-
-Babel is a powerful tool that can be explored to implement numerous useful features. If you feel like Reanimated Babel plugin could make use of some new functionality or that its pitfalls are too severe, feel free to let us know on [GitHub](https://github.com/software-mansion/react-native-reanimated/), via an issue or a discussion thread - and as always, PRs are welcome!
+For backwards compatibility we kept it as an export in Reanimated 4 but we strongly recommend using `react-native-worklets/plugin` directly.
diff --git a/docs/docs-reanimated/docs/reanimated-babel-plugin/options.md b/docs/docs-reanimated/docs/reanimated-babel-plugin/options.md
deleted file mode 100644
index 86e1791be519..000000000000
--- a/docs/docs-reanimated/docs/reanimated-babel-plugin/options.md
+++ /dev/null
@@ -1,181 +0,0 @@
----
-id: plugin-options
-title: 'Options'
-sidebar_label: 'Options'
----
-
-# Options for Reanimated Babel Plugin
-
-Our plugin offers several optional functionalities that you may need to employ advanced APIs:
-
-
-Type definitions
-
-```typescript
-interface ReanimatedPluginOptions {
- relativeSourceLocation?: boolean;
- disableInlineStylesWarning?: boolean;
- omitNativeOnlyData?: boolean;
- globals?: string[];
- substituteWebPlatformChecks?: boolean;
- disableSourceMaps?: boolean;
- extraPlugins?: string[];
- extraPresets?: string[];
-}
-```
-
-
-
-## How to use
-
-Using this is straightforward for Babel plugins; you just need to pass an object containing the options to the plugin in your `babel.config.js` file.
-
-Here's an example:
-
-```js {7}
-module.exports = {
- ...
- plugins: [
- ...
- [
- 'react-native-worklets/plugin',
- {
- relativeSourceLocation: true,
- disableInlineStylesWarning: true,
- omitNativeOnlyData: true,
- globals: ['myObjectOnUI'],
- substituteWebPlatformChecks: true,
- },
- ],
- ],
-};
-```
-
-## Options
-
-### relativeSourceLocation
-
-Defaults to `false`.
-
-This option dictates the passed file location for a worklet's source map. If you enable this option, the file paths will be relative to `process.cwd` (the current directory where Babel executes). This can be handy for Jest test snapshots to ensure consistent results across machines.
-
-### disableInlineStylesWarning
-
-Defaults to `false`.
-
-Turning on this option suppresses a helpful warning when you use [inline shared values](/docs/fundamentals/glossary#animations-in-inline-styling) and might unintentionally write:
-
-```tsx
-import Animated, {useSharedValue} from 'react-native-reanimated';
-
-function MyView() {
- const width = useSharedValue(100);
- return ; // Loss of reactivity when using `width.value` instead of `width`!
-}
-```
-
-You'll receive a warning about accessing `value` in an inline prop and the potential loss of reactivity that it causes. However, because there's no fail-safe mechanism that checks if the accessed property `value` comes from a Shared Value during Babel transpilation, it might cause problems:
-
-```tsx
-import { View } from 'react-native';
-
-interface MyProps {
- taggedWidth: {
- tag: string;
- value: number;
- };
-}
-
-function MyView({ taggedWidth }) {
- return ; // This triggers a false warning.
-}
-```
-
-Enable this option to silence such false warnings.
-
-### omitNativeOnlyData
-
-Defaults to false.
-
-This option comes in handy for Web apps. Because Babel ordinarily doesn't get information about the target platform, it includes worklet data in the bundle that only Native apps find relevant. If you enable this option, your bundle size will be smaller.
-
-### globals
-
-This is a list of identifiers (objects) that will not be copied to the UI thread if a worklet requires them. For instance:
-
-```tsx
-const someReference = 5;
-function foo() {
- 'worklet';
- return someReference + 1;
-}
-```
-
-In this example, `someReference` is not accessible on the UI thread. Consequently, we must copy it there, ensuring correct scoping, to keep the worklet from failing. But, consider this:
-
-```tsx
-function bar() {
- 'worklet';
- return null;
-}
-```
-
-Here, the identifier `null` is already accessible on the UI thread. Therefore, we don't need to copy it and use a copied value there. While it might not immediately seem particularly useful to avoid copying the value, consider the following case:
-
-```tsx
-function setOnJS() {
- global.something = 'JS THREAD';
-}
-
-function setOnUI() {
- 'worklet';
- global.something = 'UI THREAD';
-}
-
-function readFromJS() {
- console.log(global.something);
-}
-
-function readFromUI() {
- 'worklet';
- console.log(global.something);
-}
-
-function run() {
- setOnJS();
- runOnUI(setOnUI)();
- readFromJS();
- runOnUI(readFromUI)();
-}
-```
-
-Without `global` as a whitelisted identifier in this case, you'd only get:
-
-```
-JS THREAD
-JS THREAD
-```
-
-This output occurs because the entire `global` object (!) would be copied to the UI thread for it to be assigned by `setOnUI`. Then, `readOnUI` would again copy the `global` object and read from this copy.
-
-There is a [huge list of identifiers whitelisted by default](https://github.com/software-mansion/react-native-reanimated/blob/4.0.0-beta.3/packages/react-native-worklets/plugin/src/globals.ts).
-
-### substituteWebPlatformChecks
-
-Defaults to `false`.
-
-This option can also be useful for Web apps. In Reanimated, we have numerous checks to determine the right function implementation for a specific target platform. Enabling this option changes all the checks that identify if the target is a Web app to `true`. This alteration can aid in tree-shaking and contribute to reducing the bundle size.
-
-### disableSourceMaps
-
-Defaults to `false`.
-
-This option turns off the source map generation for worklets. Mostly used for testing purposes.
-
-### extraPlugins
-
-This is a list of Babel plugins that will be used when transforming worklets' code with Reanimated Babel Plugin.
-
-### extraPresets
-
-This is a list of Babel presets that will be used when transforming worklets' code with Reanimated Babel Plugin.
diff --git a/docs/docs-worklets/docs/fundamentals/glossary.mdx b/docs/docs-worklets/docs/fundamentals/glossary.mdx
index 6759ea5fbd6a..040572e774fc 100644
--- a/docs/docs-worklets/docs/fundamentals/glossary.mdx
+++ b/docs/docs-worklets/docs/fundamentals/glossary.mdx
@@ -6,47 +6,47 @@ sidebar_position: 2
## Worklet
-Worklets are short-running JavaScript functions that can be run on the [UI thread](/docs/fundamentals/glossary#ui-thread). They can also be run on a JavaScript thread just as you would run a function in your code.
+Worklet is a short-running JavaScript function that can be moved and executed across different [Worklet Runtimes](/docs/fundamentals/glossary#worklet-runtime) and the [React Native Runtime](/docs/fundamentals/glossary/#react-native-runtime-rn-runtime).
-Most of the time when working with Reanimated the code is automatically [workletized](/docs/fundamentals/glossary#to-workletize) and run on the UI thread by default.
+Most of the time when working with libraries like [Reanimated](https://docs.swmansion.com/react-native-reanimated/) the code is automatically [workletized](/docs/fundamentals/glossary#to-workletize) and run on the UI thread by default.
```javascript
const style = useAnimatedStyle(() => {
- console.log('Running on the UI thread');
+ console.log('Running on the UI Runtime (UI thread)');
return { opacity: 0.5 };
});
```
-You can create your own worklets using the `"worklet";` directive at the top of a function.
+You can create your own worklets using the `"worklet"` directive at the top of a function.
```javascript
function myWorklet() {
'worklet';
- console.log('Running on the UI thread');
+ console.log('Running on the UI Runtime (UI thread)');
}
```
-[`runOnUI`](/docs/threading/runOnUI) lets you manually run worklets on the UI thread:
+[`scheduleOnUI`](/docs/threading/scheduleOnUI) lets you manually run worklets on the UI Runtime (UI thread):
```javascript
function myWorklet(greeting) {
'worklet';
- console.log(`${greeting} from the UI thread`);
+ console.log(`${greeting} from the UI Runtime (UI thread)`);
}
function onPress() {
// highlight-next-line
- runOnUI(myWorklet)('Howdy');
+ scheduleOnUI(myWorklet, 'Howdy');
}
```
## to workletize
-To convert a JavaScript function into a serializable object which can be copied and run over on [UI thread](/docs/fundamentals/glossary#ui-thread).
+To convert a JavaScript function into a serializable object which can be copied and run over on [Worklet Runtimes](/docs/fundamentals/glossary#worklet-runtime).
-Functions marked with `"worklet";` directive are automatically picked up and workletized by the Worklets Babel plugin.
+Functions marked with `"worklet"` directive are automatically picked up and workletized by the Worklets Babel plugin.
-## Worker Worklet Runtime - Worker Runtime
+## Worklet Runtime
A JavaScript runtime spawned by `react-native-worklets`. It's pre-configured to be able to execute worklets.
@@ -56,7 +56,15 @@ You can learn more about different runtime types by reading the [Runtime kinds](
## UI Runtime
-A unique [Worklet Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime) that is tailored to efficiently offload work from the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime) and to allow for synchronous access to native events and the native rendering layer.
+A unique [Worklet Runtime](/docs/fundamentals/glossary#worklet-runtime) that is tailored to efficiently offload work from the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime) and to allow for synchronous access to native events and the native rendering layer.
+
+There's only one UI Runtime in your app.
+
+## Worker Runtime
+
+A runtime created on demand with [`createWorkletRuntime`](/docs/threading/createWorkletRuntime) function from `react-native-worklets`. You can customize its behavior and the thread it runs on.
+
+There can be multiple Worker Runtimes in your app running at the same time.
## React Native Runtime (RN Runtime)
@@ -77,29 +85,15 @@ UI thread is responsible for handling user interface updates. Also known as Main
You can learn more about it by reading the [Threading model](https://reactnative.dev/architecture/threading-model) article in the official React Native docs.
-## Animations in inline styling
-
-Passing shared values directly to `style` property without the use of `useAnimatedStyle`.
-
-For example:
-
-```jsx
-function App() {
- const width = useSharedValue(100);
-
- return ;
-}
-```
-
-## Reanimated Babel plugin
+## Worklets Babel plugin
The plugin performs automatic [workletization](/docs/fundamentals/glossary#to-workletize) of certain functions used with Reanimated to reduce the amount of boilerplate code.
-You can learn the details by reading the [Reanimated Babel plugin README](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/plugin/README-dev.md).
+You can learn the details [here](https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/about).
## Serializable
-A Serializable is an object that represents a JavaScript value that can be copied between [Worklet Runtimes](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime). JavaScript values cannot be passed to other runtimes without prior serialization.
+A Serializable is an object that represents a JavaScript value that can be copied between [Worklet Runtimes](/docs/fundamentals/glossary#worklet-runtime). JavaScript values cannot be passed to other runtimes without prior serialization.
## SerializableRef
diff --git a/docs/docs-worklets/docs/threading/isWorkletFunction.mdx b/docs/docs-worklets/docs/threading/isWorkletFunction.mdx
index 43f2b7f64334..456042bdde79 100644
--- a/docs/docs-worklets/docs/threading/isWorkletFunction.mdx
+++ b/docs/docs-worklets/docs/threading/isWorkletFunction.mdx
@@ -4,7 +4,7 @@ sidebar_position: 42 # Use alphabetical order
# isWorkletFunction
-`isWorkletFunction` checks if a function is a worklet function. It only works with Reanimated Babel plugin enabled. Unless you are doing something with internals of Reanimated you shouldn't need to use this function.
+`isWorkletFunction` checks if a function is a worklet function. It only works with Worklets Babel plugin enabled. Unless you are doing something with internals of Worklets you shouldn't need to use this function.
## Reference
diff --git a/docs/docs-worklets/docs/threading/runOnUISync.mdx b/docs/docs-worklets/docs/threading/runOnUISync.mdx
index 81c0f2470a9b..c609c2f8299f 100644
--- a/docs/docs-worklets/docs/threading/runOnUISync.mdx
+++ b/docs/docs-worklets/docs/threading/runOnUISync.mdx
@@ -51,4 +51,4 @@ Arguments to pass to the function.
- The callback passed as the argument is automatically [workletized](/docs/fundamentals/glossary#to-workletize) and ready to be run on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime).
-- Make sure not to execute `runOnUISync` on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime) or [Worker Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime) as this will result in an error.
+- Make sure not to execute `runOnUISync` on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime) or a [Worker Runtime](/docs/fundamentals/glossary#worker-runtime) as this will result in an error.
diff --git a/docs/docs-worklets/docs/threading/scheduleOnRN.mdx b/docs/docs-worklets/docs/threading/scheduleOnRN.mdx
index fd23893d1bda..b8f1ed46adb7 100644
--- a/docs/docs-worklets/docs/threading/scheduleOnRN.mdx
+++ b/docs/docs-worklets/docs/threading/scheduleOnRN.mdx
@@ -4,7 +4,7 @@ sidebar_position: 42 # Use alphabetical order
# scheduleOnRN
-`scheduleOnRN` lets you schedule a function to be executed on the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime) from any [Worklet Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+`scheduleOnRN` lets you schedule a function to be executed on the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime) from any [Worklet Runtime](/docs/fundamentals/glossary#worklet-runtime).
To learn more about the different runtime kinds, check [Runtime Kinds](/docs/fundamentals/runtimeKinds).
@@ -77,9 +77,4 @@ runOnUI(() => {
- Scheduling function from the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime) (we are already on RN Runtime) simply
uses `queueMicrotask`.
-- When functions need to be scheduled from the [UI Runtime](/docs/fundamentals/glossary#ui-runtime), first function and
- args are serialized and then the system passes the scheduling responsibility
- to the `JSScheduler`. The `JSScheduler` then uses the RN `CallInvoker` to schedule
- the function asynchronously on the JavaScript thread by calling
- `jsCallInvoker_->invokeAsync()`.
-- When called from a [Worker Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime), it uses the same JSScheduler mechanism.
+- When functions need to be scheduled from a [Worklet Runtime](/docs/fundamentals/glossary#worklet-runtime), they rely on React Native's scheduling model to forward the function call to the [RN Runtime](/docs/fundamentals/glossary#react-native-runtime-rn-runtime).
diff --git a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx
index 4b9bad4c2435..9d3b52085ebe 100644
--- a/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx
+++ b/docs/docs-worklets/docs/threading/scheduleOnRuntime.mdx
@@ -4,7 +4,7 @@ sidebar_position: 42 # Use alphabetical order
# scheduleOnRuntime
-`scheduleOnRuntime` lets you schedule a [worklet](/docs/fundamentals/glossary#worklet) to be executed on a [Worker Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+`scheduleOnRuntime` lets you schedule a [worklet](/docs/fundamentals/glossary#worklet) to be executed on a [Worker Runtime](/docs/fundamentals/glossary#worker-runtime).
## Reference
@@ -39,11 +39,11 @@ The worklet runtime to schedule the worklet on.
### worklet
-A reference to a function you want to execute on the [Worklet Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+A reference to a function you want to execute on the [Worker Runtime](/docs/fundamentals/glossary#worker-runtime).
### args
-Arguments to the function you want to execute on the [Worklet Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+Arguments to the function you want to execute on the [Worker Runtime](/docs/fundamentals/glossary#worker-runtime).
## Remarks
@@ -51,7 +51,7 @@ Arguments to the function you want to execute on the [Worklet Runtime](/docs/fun
Queue](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/Common/cpp/worklets/Public/AsyncQueue.h)
- The worklet cannot be scheduled on the Worker Runtime from [UI
Runtime](/docs/fundamentals/glossary#ui-runtime) or another [Worker
- Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime), unless the [Bundle Mode](/docs/experimental/bundleMode) is enabled.
+ Runtime](/docs/fundamentals/glossary#worker-runtime), unless the [Bundle Mode](/docs/experimental/bundleMode) is enabled.
```javascript
import { createWorkletRuntime, scheduleOnRuntime } from 'react-native-worklets';
diff --git a/docs/docs-worklets/docs/threading/scheduleOnUI.mdx b/docs/docs-worklets/docs/threading/scheduleOnUI.mdx
index 21d7a601d5e4..c2ab72e7b083 100644
--- a/docs/docs-worklets/docs/threading/scheduleOnUI.mdx
+++ b/docs/docs-worklets/docs/threading/scheduleOnUI.mdx
@@ -45,6 +45,6 @@ Arguments to pass to the function.
- The callback passed as the argument is automatically [workletized](/docs/fundamentals/glossary#to-workletize) and ready to be run on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime).
-- Make sure not to execute `scheduleOnUI` on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime) or [Worker Runtime](/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime) as this will result in an error, unless you have the [Bundle Mode](/docs/experimental/bundleMode) enabled.
+- Make sure not to execute `scheduleOnUI` on the [UI Runtime](/docs/fundamentals/glossary#ui-runtime) or [Worker Runtime](/docs/fundamentals/glossary#worker-runtime) as this will result in an error, unless you have the [Bundle Mode](/docs/experimental/bundleMode) enabled.
- On the Web, `scheduleOnUI` schedules work to run on the next animation frame using `requestAnimationFrame`.
diff --git a/docs/docs-worklets/docs/worklets-babel-plugin/options.md b/docs/docs-worklets/docs/worklets-babel-plugin/options.md
index cac51f21af2b..aa79f86979e7 100644
--- a/docs/docs-worklets/docs/worklets-babel-plugin/options.md
+++ b/docs/docs-worklets/docs/worklets-babel-plugin/options.md
@@ -12,15 +12,17 @@ Our plugin offers several optional functionalities that you may need to employ a
Type definitions
```typescript
-interface ReanimatedPluginOptions {
- relativeSourceLocation?: boolean;
+interface PluginOptions {
+ bundleMode?: boolean;
disableInlineStylesWarning?: boolean;
- omitNativeOnlyData?: boolean;
- globals?: string[];
- substituteWebPlatformChecks?: boolean;
disableSourceMaps?: boolean;
extraPlugins?: string[];
extraPresets?: string[];
+ globals?: string[];
+ omitNativeOnlyData?: boolean;
+ relativeSourceLocation?: boolean;
+ substituteWebPlatformChecks?: boolean;
+ workletizableModules?: string[];
}
```
@@ -28,24 +30,26 @@ interface ReanimatedPluginOptions {
## How to use
-Using this is straightforward for Babel plugins; you just need to pass an object containing the options to the plugin in your `babel.config.js` file.
+Using this is straightforward for Babel plugins; you just need to pass an object containing the options to the plugin in your `babel.config.js` file. Make sure to pass the plugin and its options as an two-element array.
Here's an example:
```js {7}
module.exports = {
+ /** @type {import('react-native-worklets/plugin').PluginOptions} */
+ const workletsPluginOptions = {
+ relativeSourceLocation: true,
+ disableInlineStylesWarning: true,
+ omitNativeOnlyData: true,
+ globals: ['myObjectOnUI'],
+ substituteWebPlatformChecks: true,
+ }
...
plugins: [
...
[
'react-native-worklets/plugin',
- {
- relativeSourceLocation: true,
- disableInlineStylesWarning: true,
- omitNativeOnlyData: true,
- globals: ['myObjectOnUI'],
- substituteWebPlatformChecks: true,
- },
+ workletsPluginOptions
],
],
};
@@ -53,17 +57,17 @@ module.exports = {
## Options
-### relativeSourceLocation
+### bundleMode
-Defaults to `false`.
+Default to `false`.
-This option dictates the passed file location for a worklet's source map. If you enable this option, the file paths will be relative to `process.cwd` (the current directory where Babel executes). This can be handy for Jest test snapshots to ensure consistent results across machines.
+Enables the [Bundle Mode](/docs/experimental/bundle-mode).
### disableInlineStylesWarning
Defaults to `false`.
-Turning on this option suppresses a helpful warning when you use [inline shared values](/docs/fundamentals/glossary#animations-in-inline-styling) and might unintentionally write:
+Turning on this option suppresses a helpful warning when you use [inline shared values](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animations-in-inline-styling) and might unintentionally write:
```tsx
import Animated, {useSharedValue} from 'react-native-reanimated';
@@ -93,14 +97,28 @@ function MyView({ taggedWidth }) {
Enable this option to silence such false warnings.
-### omitNativeOnlyData
+### disableSourceMaps
-Defaults to false.
+Defaults to `false`.
-This option comes in handy for Web apps. Because Babel ordinarily doesn't get information about the target platform, it includes worklet data in the bundle that only Native apps find relevant. If you enable this option, your bundle size will be smaller.
+This option turns off the source map generation for worklets. Mostly used for testing purposes.
+
+### extraPlugins
+
+Defaults to an empty array.
+
+This is a list of Babel plugins that will be used when transforming worklets' code with Worklets Babel Plugin.
+
+### extraPresets
+
+Defaults to an empty array.
+
+This is a list of Babel presets that will be used when transforming worklets' code with Worklets Babel Plugin.
### globals
+Defaults to an empty array.
+
This is a list of identifiers (objects) that will not be copied to the UI thread if a worklet requires them. For instance:
```tsx
@@ -158,24 +176,28 @@ JS THREAD
This output occurs because the entire `global` object (!) would be copied to the UI thread for it to be assigned by `setOnUI`. Then, `readOnUI` would again copy the `global` object and read from this copy.
-There is a [huge list of identifiers whitelisted by default](https://github.com/software-mansion/react-native-reanimated/blob/4.0.0-beta.3/packages/react-native-worklets/plugin/src/globals.ts).
+There is a [huge list of identifiers whitelisted by default](https://github.com/software-mansion/react-native-reanimated/blob/main/packages/react-native-worklets/plugin/src/globals.ts).
-### substituteWebPlatformChecks
+### omitNativeOnlyData
Defaults to `false`.
-This option can also be useful for Web apps. In Reanimated, we have numerous checks to determine the right function implementation for a specific target platform. Enabling this option changes all the checks that identify if the target is a Web app to `true`. This alteration can aid in tree-shaking and contribute to reducing the bundle size.
+This option comes in handy for Web apps. Because Babel ordinarily doesn't get information about the target platform, it includes worklet data in the bundle that only Native apps find relevant. If you enable this option, your bundle size will be smaller.
-### disableSourceMaps
+### relativeSourceLocation
Defaults to `false`.
-This option turns off the source map generation for worklets. Mostly used for testing purposes.
+This option dictates the passed file location for a worklet's source map. If you enable this option, the file paths will be relative to `process.cwd` (the current directory where Babel executes). This can be handy for Jest test snapshots to ensure consistent results across machines.
-### extraPlugins
+### substituteWebPlatformChecks
-This is a list of Babel plugins that will be used when transforming worklets' code with Worklets Babel Plugin.
+Defaults to `false`.
-### extraPresets
+This option can also be useful for Web apps. In Reanimated, there are numerous checks to determine the right function implementation for a specific target platform. Enabling this option changes all the checks that identify if the target is a Web app to `true`. This alteration can aid in tree-shaking and contribute to reducing the bundle size.
-This is a list of Babel presets that will be used when transforming worklets' code with Worklets Babel Plugin.
+### workletizableModules
+
+Defaults to an empty array.
+
+This option allows you to register modules as safe to use on Worklet Runtimes in the [Bundle Mode](/docs/experimental/bundle-mode).
diff --git a/docs/docs-worklets/src/components/AvailableFrom/index.tsx b/docs/docs-worklets/src/components/AvailableFrom/index.tsx
new file mode 100644
index 000000000000..56b8b2b42f9f
--- /dev/null
+++ b/docs/docs-worklets/src/components/AvailableFrom/index.tsx
@@ -0,0 +1,44 @@
+import { useColorMode } from '@docusaurus/theme-common';
+import clsx from 'clsx';
+import React from 'react';
+
+import Danger from '/static/img/danger.svg';
+import DangerDark from '/static/img/danger-dark.svg';
+
+import styles from './styles.module.css';
+
+interface Props {
+ version?: string;
+ isFull?: boolean;
+}
+
+export default function AvailableFrom({ version, isFull }: Props) {
+ const { colorMode } = useColorMode();
+ const isLightMode = colorMode === 'light';
+ const badgeThemeStyles = isLightMode ? styles.light : styles.dark;
+
+ const getBadgeContent = () => {
+ if (isFull) {
+ return (
+ <>
+
+ {isLightMode ? : }
+
+ Available from {version}
+ >
+ );
+ }
+
+ return <>Available from {version}>;
+ };
+
+ return (
+
+ {getBadgeContent()}
+
+ );
+}
diff --git a/docs/docs-worklets/src/components/AvailableFrom/styles.module.css b/docs/docs-worklets/src/components/AvailableFrom/styles.module.css
new file mode 100644
index 000000000000..1b5faa6f1bef
--- /dev/null
+++ b/docs/docs-worklets/src/components/AvailableFrom/styles.module.css
@@ -0,0 +1,41 @@
+.badge {
+ display: inline-block;
+ border-radius: 8px;
+ font-size: 12px;
+ font-weight: 500;
+ padding: 0.25rem 0.5rem;
+ white-space: nowrap;
+ margin: 0 0.25rem;
+}
+
+.fullBadge {
+ padding: 1rem;
+ width: '100%';
+ border-radius: 8px;
+ display: flex !important;
+ flex-direction: row;
+ margin-bottom: 1rem;
+}
+
+.light {
+ background-color: var(--swm-yellow-light-40);
+ color: var(--swm-navy-light-100);
+}
+
+.dark {
+ background-color: var(--swm-yellow-dark-120);
+ color: var(--swm-off-white);
+}
+
+.infoIcon {
+ margin-right: 1rem;
+}
+
+.infoIcon > svg {
+ width: 14px;
+ height: 14px;
+}
+
+.version {
+ font-weight: 500;
+}
diff --git a/packages/react-native-reanimated/babel.config.js b/packages/react-native-reanimated/babel.config.js
index 0d412dc419d1..87a3254f7788 100644
--- a/packages/react-native-reanimated/babel.config.js
+++ b/packages/react-native-reanimated/babel.config.js
@@ -1,3 +1,6 @@
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = { disableInlineStylesWarning: true };
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: [
@@ -12,7 +15,5 @@ module.exports = {
'@babel/preset-typescript',
'module:@react-native/babel-preset',
],
- plugins: [
- ['react-native-worklets/plugin', { disableInlineStylesWarning: true }],
- ],
+ plugins: [['react-native-worklets/plugin', workletOptions]],
};
diff --git a/packages/react-native-reanimated/plugin/index.d.ts b/packages/react-native-reanimated/plugin/index.d.ts
new file mode 100644
index 000000000000..d97c91acd041
--- /dev/null
+++ b/packages/react-native-reanimated/plugin/index.d.ts
@@ -0,0 +1 @@
+export type { PluginOptions } from 'react-native-worklets/plugin/';
diff --git a/packages/react-native-reanimated/src/hook/useAnimatedReaction.ts b/packages/react-native-reanimated/src/hook/useAnimatedReaction.ts
index 707876290872..7382c301dce6 100644
--- a/packages/react-native-reanimated/src/hook/useAnimatedReaction.ts
+++ b/packages/react-native-reanimated/src/hook/useAnimatedReaction.ts
@@ -42,7 +42,7 @@ export function useAnimatedReaction(
if (SHOULD_BE_USE_WEB) {
if (!inputs.length && dependencies?.length) {
- // let web work without a Reanimated Babel plugin
+ // let web work without Worklets Babel plugin
inputs = dependencies;
}
}
diff --git a/packages/react-native-worklets/package.json b/packages/react-native-worklets/package.json
index 0520e652e017..a645e80e0dde 100644
--- a/packages/react-native-worklets/package.json
+++ b/packages/react-native-worklets/package.json
@@ -104,6 +104,7 @@
"scripts/worklets_utils.rb",
"scripts/validate-react-native-version.js",
"plugin/index.js",
+ "plugin/index.d.ts",
"*.podspec",
"react-native.config.js",
"!apple/build",
diff --git a/packages/react-native-worklets/plugin/.gitignore b/packages/react-native-worklets/plugin/.gitignore
index 8a87d091fb71..2ef7f55c8137 100644
--- a/packages/react-native-worklets/plugin/.gitignore
+++ b/packages/react-native-worklets/plugin/.gitignore
@@ -1,2 +1,3 @@
lib
+types
index.js.map
diff --git a/packages/react-native-worklets/plugin/.prettierignore b/packages/react-native-worklets/plugin/.prettierignore
index 1ff46ee3db30..637d1ba1da97 100644
--- a/packages/react-native-worklets/plugin/.prettierignore
+++ b/packages/react-native-worklets/plugin/.prettierignore
@@ -1,3 +1,5 @@
index.js
index.js.map
+index.d.ts
lib/
+types/
diff --git a/packages/react-native-worklets/plugin/babel.config.js b/packages/react-native-worklets/plugin/babel.config.js
index 46391e14f502..51505b5f628f 100644
--- a/packages/react-native-worklets/plugin/babel.config.js
+++ b/packages/react-native-worklets/plugin/babel.config.js
@@ -1,15 +1,13 @@
// This file is needed for manual tests of the plugin.
const workletsPlugin = require('./index.js');
+/** @type {import('react-native-worklets/plugin').PluginOptions} */
+const workletOptions = {
+ // bundleMode: true,
+};
+
/** @type {import('@babel/core').TransformOptions} */
module.exports = {
presets: ['@babel/preset-typescript'],
- plugins: [
- [
- workletsPlugin,
- {
- // bundleMode: true,
- },
- ],
- ],
+ plugins: [[workletsPlugin, workletOptions]],
};
diff --git a/packages/react-native-worklets/plugin/index.d.ts b/packages/react-native-worklets/plugin/index.d.ts
new file mode 100644
index 000000000000..ef2faca5a2c9
--- /dev/null
+++ b/packages/react-native-worklets/plugin/index.d.ts
@@ -0,0 +1,12 @@
+export interface PluginOptions {
+ bundleMode?: boolean;
+ disableInlineStylesWarning?: boolean;
+ disableSourceMaps?: boolean;
+ extraPlugins?: string[];
+ extraPresets?: string[];
+ globals?: string[];
+ omitNativeOnlyData?: boolean;
+ relativeSourceLocation?: boolean;
+ substituteWebPlatformChecks?: boolean;
+ workletizableModules?: string[];
+}
diff --git a/packages/react-native-worklets/plugin/package.json b/packages/react-native-worklets/plugin/package.json
index 8b882f581b73..e651f7cc81c0 100644
--- a/packages/react-native-worklets/plugin/package.json
+++ b/packages/react-native-worklets/plugin/package.json
@@ -22,9 +22,9 @@
"license": "MIT",
"readmeFilename": "README.md",
"scripts": {
- "build": "yarn tsc && yarn bundle && yarn format",
+ "build": "yarn tsc && yarn bundle && yarn format && yarn format && cp types/options.d.ts index.d.ts",
"bundle": "node bundle.js",
- "format": "prettier --write --list-different src",
+ "format": "prettier --write --ignore-path '' --log-level silent types/options.d.ts && prettier --write --list-different src",
"watch": "tsc-watch --onSuccess \"yarn bundle\"",
"lint": "eslint --max-warnings=0 src",
"type:check": "tsc --noEmit"
diff --git a/packages/react-native-worklets/plugin/src/autoworkletization.ts b/packages/react-native-worklets/plugin/src/autoworkletization.ts
index 2342dc7c7f97..4957a60e133d 100644
--- a/packages/react-native-worklets/plugin/src/autoworkletization.ts
+++ b/packages/react-native-worklets/plugin/src/autoworkletization.ts
@@ -11,9 +11,9 @@ import { isLayoutAnimationCallback } from './layoutAnimationAutoworkletization';
import { processWorkletizableObject } from './objectWorklets';
import { findReferencedWorklet } from './referencedWorklets';
import type {
- ReanimatedPluginPass,
WorkletizableFunction,
WorkletizableObject,
+ WorkletsPluginPass,
} from './types';
import {
isWorkletizableFunctionPath,
@@ -71,7 +71,7 @@ const reanimatedFunctionArgsToWorkletize = new Map([
/** @returns `true` if the function was workletized, `false` otherwise. */
export function processIfAutoworkletizableCallback(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): boolean {
if (isGestureHandlerEventCallback(path) || isLayoutAnimationCallback(path)) {
processWorklet(path, state);
@@ -82,7 +82,7 @@ export function processIfAutoworkletizableCallback(
export function processCalleesAutoworkletizableCallbacks(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): void {
const callee = isSequenceExpression(path.node.callee)
? path.node.callee.expressions[path.node.callee.expressions.length - 1]
@@ -120,7 +120,7 @@ export function processCalleesAutoworkletizableCallbacks(
function processArgs(
args: NodePath[],
- state: ReanimatedPluginPass,
+ state: WorkletsPluginPass,
acceptWorkletizableFunction: boolean,
acceptObject: boolean
): void {
@@ -148,7 +148,7 @@ function findWorklet(
arg: NodePath,
acceptWorkletizableFunction: boolean,
acceptObject: boolean,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): NodePath | NodePath | undefined {
if (acceptWorkletizableFunction && isWorkletizableFunctionPath(arg)) {
return arg;
diff --git a/packages/react-native-worklets/plugin/src/bundleMode.ts b/packages/react-native-worklets/plugin/src/bundleMode.ts
index c2f8bf97657d..7576e99219bf 100644
--- a/packages/react-native-worklets/plugin/src/bundleMode.ts
+++ b/packages/react-native-worklets/plugin/src/bundleMode.ts
@@ -1,7 +1,7 @@
import type { NodePath } from '@babel/core';
import { booleanLiteral, type ExpressionStatement } from '@babel/types';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
/**
* This function replaces the `false` value in
@@ -15,7 +15,7 @@ import type { ReanimatedPluginPass } from './types';
*/
export function toggleBundleMode(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
if (
!state.opts.bundleMode ||
diff --git a/packages/react-native-worklets/plugin/src/class.ts b/packages/react-native-worklets/plugin/src/class.ts
index 952177d0c97d..bf47e883ff22 100644
--- a/packages/react-native-worklets/plugin/src/class.ts
+++ b/packages/react-native-worklets/plugin/src/class.ts
@@ -34,7 +34,7 @@ import {
import { strict as assert } from 'assert';
import { workletTransformSync } from './transform';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import { workletClassFactorySuffix } from './types';
import { replaceWithFactoryCall } from './utils';
@@ -42,7 +42,7 @@ const classWorkletMarker = '__workletClass';
export function processIfWorkletClass(
classPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): boolean {
if (
!isWorkletizableClass(classPath, state) ||
@@ -60,7 +60,7 @@ export function processIfWorkletClass(
function processClass(
classPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
assert(classPath.node.id);
const className = classPath.node.id.name;
@@ -91,7 +91,7 @@ function processClass(
function getPolyfilledAst(
classNode: ClassDeclaration,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
const classCode = generate(classNode).code;
@@ -346,7 +346,7 @@ type Polyfill = {
function isWorkletizableClass(
classPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): boolean {
const className = classPath.node.id?.name;
const classNode = classPath.node;
diff --git a/packages/react-native-worklets/plugin/src/closure.ts b/packages/react-native-worklets/plugin/src/closure.ts
index dc1b798256bd..d0302d1c7410 100644
--- a/packages/react-native-worklets/plugin/src/closure.ts
+++ b/packages/react-native-worklets/plugin/src/closure.ts
@@ -8,11 +8,11 @@ import {
internalBindingsToCaptureFromGlobalScope,
outsideBindingsToCaptureFromGlobalScope,
} from './globals';
-import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
+import type { WorkletizableFunction, WorkletsPluginPass } from './types';
export function getClosure(
funPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): {
closureVariables: Identifier[];
libraryBindingsToImport: Set;
diff --git a/packages/react-native-worklets/plugin/src/contextObject.ts b/packages/react-native-worklets/plugin/src/contextObject.ts
index 11f02d9b6c63..1d9fb7851736 100644
--- a/packages/react-native-worklets/plugin/src/contextObject.ts
+++ b/packages/react-native-worklets/plugin/src/contextObject.ts
@@ -13,13 +13,13 @@ import {
returnStatement,
} from '@babel/types';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
export const contextObjectMarker = '__workletContextObject';
export function processIfWorkletContextObject(
path: NodePath,
- _state: ReanimatedPluginPass
+ _state: WorkletsPluginPass
): boolean {
if (!isContextObject(path.node)) {
return false;
diff --git a/packages/react-native-worklets/plugin/src/file.ts b/packages/react-native-worklets/plugin/src/file.ts
index 18a115012f24..e0f41bb4d517 100644
--- a/packages/react-native-worklets/plugin/src/file.ts
+++ b/packages/react-native-worklets/plugin/src/file.ts
@@ -28,7 +28,7 @@ import {
} from '@babel/types';
import { contextObjectMarker } from './contextObject';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import {
isWorkletizableFunctionPath,
isWorkletizableObjectPath,
@@ -36,7 +36,7 @@ import {
export function processIfWorkletFile(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): boolean {
if (
!path.node.directives.some(
@@ -58,7 +58,7 @@ export function processIfWorkletFile(
/** Adds a worklet directive to each viable top-level entity in the file. */
function processWorkletFile(
programPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
const statements = programPath.get('body');
dehoistCommonJSExports(programPath.node);
@@ -81,7 +81,7 @@ function getCandidate(statementPath: NodePath) {
function processWorkletizableEntity(
nodePath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
if (isWorkletizableFunctionPath(nodePath)) {
if (nodePath.isArrowFunctionExpression()) {
@@ -110,7 +110,7 @@ function processWorkletizableEntity(
function processVariableDeclaration(
variableDeclarationPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
const declarations = variableDeclarationPath.get('declarations');
declarations.forEach((declaration) => {
@@ -123,7 +123,7 @@ function processVariableDeclaration(
function processWorkletAggregator(
objectPath: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
const properties = objectPath.get('properties');
properties.forEach((property) => {
diff --git a/packages/react-native-worklets/plugin/src/generate.ts b/packages/react-native-worklets/plugin/src/generate.ts
index fe281eece81e..425044e26605 100644
--- a/packages/react-native-worklets/plugin/src/generate.ts
+++ b/packages/react-native-worklets/plugin/src/generate.ts
@@ -16,7 +16,7 @@ import assert from 'assert';
import { existsSync, mkdirSync, writeFileSync } from 'fs';
import { dirname, relative, resolve } from 'path';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import { generatedWorkletsDir } from './types';
export function generateWorkletFile(
@@ -24,7 +24,7 @@ export function generateWorkletFile(
relativeBindingsToImport: Set,
factory: FunctionExpression,
workletHash: number,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
const libraryImports = Array.from(libraryBindingsToImport)
.filter(
diff --git a/packages/react-native-worklets/plugin/src/globals.ts b/packages/react-native-worklets/plugin/src/globals.ts
index 5495da9ab7e2..e2c27e42811d 100644
--- a/packages/react-native-worklets/plugin/src/globals.ts
+++ b/packages/react-native-worklets/plugin/src/globals.ts
@@ -1,4 +1,4 @@
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
const notCapturedIdentifiers = [
// Based on https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects
@@ -148,7 +148,7 @@ export const internalBindingsToCaptureFromGlobalScope = new Set([
// eslint-disable-next-line camelcase
const notCapturedIdentifiers_DEPRECATED = ['_IS_FABRIC'];
-export function initializeState(state: ReanimatedPluginPass) {
+export function initializeState(state: WorkletsPluginPass) {
state.workletNumber = 1;
state.classesToWorkletize = [];
initializeGlobals();
@@ -177,7 +177,7 @@ export function initializeGlobals() {
* ];
* ```
*/
-export function addCustomGlobals(state: ReanimatedPluginPass) {
+export function addCustomGlobals(state: WorkletsPluginPass) {
if (state.opts && Array.isArray(state.opts.globals)) {
state.opts.globals.forEach((name: string) => {
globals.add(name);
diff --git a/packages/react-native-worklets/plugin/src/inlineStylesWarning.ts b/packages/react-native-worklets/plugin/src/inlineStylesWarning.ts
index ec65df57c2f5..905c4da8f301 100644
--- a/packages/react-native-worklets/plugin/src/inlineStylesWarning.ts
+++ b/packages/react-native-worklets/plugin/src/inlineStylesWarning.ts
@@ -20,7 +20,7 @@ import {
} from '@babel/types';
import { strict as assert } from 'assert';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import { isRelease } from './utils';
function generateInlineStylesWarning(path: NodePath) {
@@ -101,7 +101,7 @@ function processStyleObjectForInlineStylesWarning(
export function processInlineStylesWarning(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
if (isRelease()) {
return;
diff --git a/packages/react-native-worklets/plugin/src/objectWorklets.ts b/packages/react-native-worklets/plugin/src/objectWorklets.ts
index d62f5193cc02..898970290371 100644
--- a/packages/react-native-worklets/plugin/src/objectWorklets.ts
+++ b/packages/react-native-worklets/plugin/src/objectWorklets.ts
@@ -1,12 +1,12 @@
import type { NodePath } from '@babel/core';
-import type { ReanimatedPluginPass, WorkletizableObject } from './types';
+import type { WorkletizableObject, WorkletsPluginPass } from './types';
import { isWorkletizableFunctionPath } from './types';
import { processWorklet } from './workletSubstitution';
export function processWorkletizableObject(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): void {
const properties = path.get('properties');
for (const property of properties) {
diff --git a/packages/react-native-worklets/plugin/src/options.ts b/packages/react-native-worklets/plugin/src/options.ts
new file mode 100644
index 000000000000..0b293f2f2ea8
--- /dev/null
+++ b/packages/react-native-worklets/plugin/src/options.ts
@@ -0,0 +1,109 @@
+export interface PluginOptions {
+ /**
+ * Enables the [Bundle
+ * Mode](https://docs.swmansion.com/react-native-worklets/docs/experimental/bundle-mode).
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#bundle-mode}
+ *
+ * - Defaults to `false`.
+ */
+ bundleMode?: boolean;
+
+ /**
+ * Turning on this option suppresses a helpful warning when you use [inline
+ * shared
+ * values](https://docs.swmansion.com/react-native-reanimated/docs/fundamentals/glossary#animations-in-inline-styling).
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#disableinlinestyleswarning}
+ *
+ * - Defaults to `false`.
+ */
+ disableInlineStylesWarning?: boolean;
+
+ /**
+ * This option turns off the source map generation for worklets. Mostly used
+ * for testing purposes.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#disablesourcemaps}
+ *
+ * - Defaults to `false`.
+ */
+ disableSourceMaps?: boolean;
+
+ /**
+ * This is a list of Babel plugins that will be used when transforming
+ * worklets' code with Worklets Babel Plugin.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#extraplugins}
+ *
+ * - Defaults to an empty array `[]`.
+ */
+ extraPlugins?: string[];
+
+ /**
+ * This is a list of Babel presets that will be used when transforming
+ * worklets' code with Worklets Babel Plugin.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#extrapresets}
+ *
+ * - Defaults to an empty array `[]`.
+ */
+ extraPresets?: string[];
+
+ /**
+ * This is a list of identifiers (objects) that will not be copied to the UI
+ * thread if a worklet requires them.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#globals}
+ *
+ * - Defaults to an empty array `[]`.
+ */
+ globals?: string[];
+
+ /**
+ * This option comes in handy for Web apps. Because Babel ordinarily doesn't
+ * get information about the target platform, it includes worklet data in the
+ * bundle that only Native apps find relevant. If you enable this option, your
+ * bundle size will be smaller.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#omitnativeonlydata}
+ *
+ * - Defaults to `false`.
+ */
+ omitNativeOnlyData?: boolean;
+
+ /**
+ * This option dictates the passed file location for a worklet's source map.
+ * If you enable this option, the file paths will be relative to `process.cwd`
+ * (the current directory where Babel executes). This can be handy for Jest
+ * test snapshots to ensure consistent results across machines.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#relativesourcelocation}
+ *
+ * - Defaults to `false`.
+ */
+ relativeSourceLocation?: boolean;
+
+ /**
+ * This option can also be useful for Web apps. In Reanimated, there are
+ * numerous checks to determine the right function implementation for a
+ * specific target platform. Enabling this option changes all the checks that
+ * identify if the target is a Web app to `true`. This alteration can aid in
+ * tree-shaking and contribute to reducing the bundle size.
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#substitutewebplatformchecks}
+ *
+ * - Defaults to `false`.
+ */
+ substituteWebPlatformChecks?: boolean;
+
+ /**
+ * This option allows you to register modules as safe to use on Worklet
+ * Runtimes in the [Bundle Mode](/docs/experimental/bundle-mode).
+ *
+ * {@link https://docs.swmansion.com/react-native-worklets/docs/worklets-babel-plugin/plugin-options#workletizablemodules}
+ *
+ * - Defaults to an empty array `[]`.
+ */
+ workletizableModules?: string[];
+}
diff --git a/packages/react-native-worklets/plugin/src/plugin.ts b/packages/react-native-worklets/plugin/src/plugin.ts
index b7a3d3bcf204..4e851c1050f4 100644
--- a/packages/react-native-worklets/plugin/src/plugin.ts
+++ b/packages/react-native-worklets/plugin/src/plugin.ts
@@ -18,7 +18,7 @@ import { processIfWorkletContextObject } from './contextObject';
import { processIfWorkletFile } from './file';
import { initializeState } from './globals';
import { processInlineStylesWarning } from './inlineStylesWarning';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import { WorkletizableFunction } from './types';
import { substituteWebCallExpression } from './webOptimization';
import { processIfWithWorkletDirective } from './workletSubstitution';
@@ -38,14 +38,14 @@ module.exports = function WorkletsBabelPlugin(): PluginItem {
return {
name: 'worklets',
- pre(this: ReanimatedPluginPass) {
+ pre(this: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
initializeState(this);
});
},
visitor: {
CallExpression: {
- enter(path: NodePath, state: ReanimatedPluginPass) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
processCalleesAutoworkletizableCallbacks(path, state);
if (state.opts.substituteWebPlatformChecks) {
@@ -57,7 +57,7 @@ module.exports = function WorkletsBabelPlugin(): PluginItem {
[WorkletizableFunction]: {
enter(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
) {
runWithTaggedExceptions(
() =>
@@ -67,38 +67,35 @@ module.exports = function WorkletsBabelPlugin(): PluginItem {
},
},
ObjectExpression: {
- enter(path: NodePath, state: ReanimatedPluginPass) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
processIfWorkletContextObject(path, state);
});
},
},
ClassDeclaration: {
- enter(path: NodePath, state: ReanimatedPluginPass) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
processIfWorkletClass(path, state);
});
},
},
Program: {
- enter(path: NodePath, state: ReanimatedPluginPass) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
processIfWorkletFile(path, state);
});
},
},
ExpressionStatement: {
- enter(
- path: NodePath,
- state: ReanimatedPluginPass
- ) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() => {
toggleBundleMode(path, state);
});
},
},
JSXAttribute: {
- enter(path: NodePath, state: ReanimatedPluginPass) {
+ enter(path: NodePath, state: WorkletsPluginPass) {
runWithTaggedExceptions(() =>
processInlineStylesWarning(path, state)
);
diff --git a/packages/react-native-worklets/plugin/src/referencedWorklets.ts b/packages/react-native-worklets/plugin/src/referencedWorklets.ts
index 13f36d743d81..b0930354f1b5 100644
--- a/packages/react-native-worklets/plugin/src/referencedWorklets.ts
+++ b/packages/react-native-worklets/plugin/src/referencedWorklets.ts
@@ -4,9 +4,9 @@ import type { AssignmentExpression, Identifier } from '@babel/types';
import { isIdentifier, isMemberExpression } from '@babel/types';
import type {
- ReanimatedPluginPass,
WorkletizableFunction,
WorkletizableObject,
+ WorkletsPluginPass,
} from './types';
import {
isWorkletizableFunctionPath,
@@ -17,7 +17,7 @@ export function findReferencedWorklet(
workletIdentifier: NodePath,
acceptWorkletizableFunction: boolean,
acceptObject: boolean,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): NodePath | NodePath | undefined {
const workletName = workletIdentifier.node.name;
const scope = workletIdentifier.scope;
@@ -59,7 +59,7 @@ function findReferencedWorkletFromVariableDeclarator(
workletBinding: Binding,
acceptWorkletizableFunction: boolean,
acceptObject: boolean,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): NodePath | NodePath | undefined {
const workletDeclaration = workletBinding.path;
if (!workletDeclaration.isVariableDeclarator()) {
@@ -88,7 +88,7 @@ function findReferencedWorkletFromAssignmentExpression(
workletBinding: Binding,
acceptWorkletizableFunction: boolean,
acceptObject: boolean,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): NodePath | NodePath | undefined {
const workletDeclaration = workletBinding.constantViolations
.reverse()
diff --git a/packages/react-native-worklets/plugin/src/types.ts b/packages/react-native-worklets/plugin/src/types.ts
index 50d3902b82f1..52b9e180b0f3 100644
--- a/packages/react-native-worklets/plugin/src/types.ts
+++ b/packages/react-native-worklets/plugin/src/types.ts
@@ -15,23 +15,12 @@ import {
isObjectMethod,
} from '@babel/types';
-export interface ReanimatedPluginOptions {
- relativeSourceLocation?: boolean;
- disableInlineStylesWarning?: boolean;
- omitNativeOnlyData?: boolean;
- globals?: string[];
- substituteWebPlatformChecks?: boolean;
- disableSourceMaps?: boolean;
- extraPlugins?: string[];
- extraPresets?: string[];
- bundleMode?: boolean;
- workletizableModules?: string[];
-}
+import type { PluginOptions } from './options';
-export interface ReanimatedPluginPass {
+export interface WorkletsPluginPass {
file: BabelFile;
key: string;
- opts: ReanimatedPluginOptions;
+ opts: PluginOptions;
cwd: string;
filename: string | undefined;
workletNumber: number;
diff --git a/packages/react-native-worklets/plugin/src/workletFactory.ts b/packages/react-native-worklets/plugin/src/workletFactory.ts
index 232ab221465a..d7386282a76e 100644
--- a/packages/react-native-worklets/plugin/src/workletFactory.ts
+++ b/packages/react-native-worklets/plugin/src/workletFactory.ts
@@ -38,7 +38,7 @@ import { basename, relative } from 'path';
import { getClosure } from './closure';
import { generateWorkletFile } from './generate';
import { workletTransformSync } from './transform';
-import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
+import type { WorkletizableFunction, WorkletsPluginPass } from './types';
import { workletClassFactorySuffix } from './types';
import { isRelease } from './utils';
import { buildWorkletString } from './workletStringCode';
@@ -50,7 +50,7 @@ const MOCK_VERSION = 'x.y.z';
export function makeWorkletFactory(
fun: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): {
factory: FunctionExpression;
factoryCallParamPack: ObjectExpression;
@@ -425,7 +425,7 @@ function hash(str: string): number {
function makeWorkletName(
fun: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): { workletName: string; reactName: string } {
let source = 'unknownFile';
diff --git a/packages/react-native-worklets/plugin/src/workletFactoryCall.ts b/packages/react-native-worklets/plugin/src/workletFactoryCall.ts
index c085f56e17bf..a9ae832d60e9 100644
--- a/packages/react-native-worklets/plugin/src/workletFactoryCall.ts
+++ b/packages/react-native-worklets/plugin/src/workletFactoryCall.ts
@@ -7,13 +7,13 @@ import {
stringLiteral,
} from '@babel/types';
-import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
+import type { WorkletizableFunction, WorkletsPluginPass } from './types';
import { generatedWorkletsDir } from './types';
import { makeWorkletFactory } from './workletFactory';
export function makeWorkletFactoryCall(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): CallExpression {
const { factory, factoryCallParamPack, workletHash } = makeWorkletFactory(
path,
diff --git a/packages/react-native-worklets/plugin/src/workletStringCode.ts b/packages/react-native-worklets/plugin/src/workletStringCode.ts
index 06f503266e77..b2ec7559029a 100644
--- a/packages/react-native-worklets/plugin/src/workletStringCode.ts
+++ b/packages/react-native-worklets/plugin/src/workletStringCode.ts
@@ -31,7 +31,7 @@ import * as convertSourceMap from 'convert-source-map';
import * as fs from 'fs';
import { workletTransformSync } from './transform';
-import type { ReanimatedPluginPass, WorkletizableFunction } from './types';
+import type { WorkletizableFunction, WorkletsPluginPass } from './types';
import { workletClassFactorySuffix } from './types';
import { isRelease } from './utils';
@@ -39,7 +39,7 @@ const MOCK_SOURCE_MAP = 'mock source map';
export function buildWorkletString(
fun: BabelFile,
- state: ReanimatedPluginPass,
+ state: WorkletsPluginPass,
closureVariables: Array,
workletName: string,
inputMap: BabelFileResult['map']
diff --git a/packages/react-native-worklets/plugin/src/workletSubstitution.ts b/packages/react-native-worklets/plugin/src/workletSubstitution.ts
index 29e10f6fdbb3..c0d5305cf9b2 100644
--- a/packages/react-native-worklets/plugin/src/workletSubstitution.ts
+++ b/packages/react-native-worklets/plugin/src/workletSubstitution.ts
@@ -6,7 +6,7 @@ import {
objectProperty,
} from '@babel/types';
-import type { ReanimatedPluginPass } from './types';
+import type { WorkletsPluginPass } from './types';
import { WorkletizableFunction } from './types';
import { replaceWithFactoryCall } from './utils';
import { makeWorkletFactoryCall } from './workletFactoryCall';
@@ -14,7 +14,7 @@ import { makeWorkletFactoryCall } from './workletFactoryCall';
/** @returns `true` if the function was workletized, `false` otherwise. */
export function processIfWithWorkletDirective(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): boolean {
if (!isBlockStatement(path.node.body)) {
// If the function body is not a block statement we can safely assume that it's not a worklet
@@ -41,14 +41,14 @@ export function processIfWithWorkletDirective(
*/
export function processWorklet(
path: NodePath,
- state: ReanimatedPluginPass
+ state: WorkletsPluginPass
): void {
path.traverse(
{
// @ts-expect-error TypeScript doesn't like this syntax here.
[WorkletizableFunction](
subPath: NodePath,
- passedState: ReanimatedPluginPass
+ passedState: WorkletsPluginPass
): void {
processIfWithWorkletDirective(subPath, passedState);
},
diff --git a/packages/react-native-worklets/plugin/tsconfig.json b/packages/react-native-worklets/plugin/tsconfig.json
index 73b5f7c32c4b..a2d130acd013 100644
--- a/packages/react-native-worklets/plugin/tsconfig.json
+++ b/packages/react-native-worklets/plugin/tsconfig.json
@@ -10,7 +10,8 @@
"esModuleInterop": true,
"outDir": "lib",
"rootDir": "src",
- "declaration": false,
+ "declarationDir": "types",
+ "declaration": true,
"noEmit": false
},
"include": ["src"]
diff --git a/packages/react-native-worklets/src/runtimes.native.ts b/packages/react-native-worklets/src/runtimes.native.ts
index b355ff79cf6f..5cd234e89b90 100644
--- a/packages/react-native-worklets/src/runtimes.native.ts
+++ b/packages/react-native-worklets/src/runtimes.native.ts
@@ -107,8 +107,8 @@ export function createWorkletRuntime(
/**
* Lets you asynchronously run a
* [worklet](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worklet)
- * on the [Worker
- * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+ * on a [Worker
+ * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-runtime).
*
* Check
* {@link https://docs.swmansion.com/react-native-worklets/docs/fundamentals/runtimeKinds}
@@ -119,7 +119,7 @@ export function createWorkletRuntime(
* - The function cannot be scheduled on the Worker Runtime from [UI
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime)
* or another [Worker
- * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime),
+ * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-runtime),
* unless the [Bundle
* Mode](https://docs.swmansion.com/react-native-worklets/docs/experimental/bundleMode)
* is enabled.
diff --git a/packages/react-native-worklets/src/threads.native.ts b/packages/react-native-worklets/src/threads.native.ts
index 6d6735e0a646..96413a0147c1 100644
--- a/packages/react-native-worklets/src/threads.native.ts
+++ b/packages/react-native-worklets/src/threads.native.ts
@@ -64,8 +64,8 @@ export const callMicrotasks = callMicrotasksOnUIThread;
* and serialized.
* - This function cannot be called from the [UI
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime)
- * or [Worker
- * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime),
+ * or a [Worker
+ * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-runtime),
* unless you have the [Bundle Mode](/docs/experimental/bundleMode) enabled.
*
* @param fun - A reference to a function you want to schedule on the [UI
@@ -168,7 +168,7 @@ if (__DEV__) {
* - This function cannot be called from the [UI
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime).
* - This function cannot be called from a [Worker
- * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-worklet-runtime---worker-runtime).
+ * Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#worker-runtime).
*
* @param fun - A reference to a function you want to execute on the [UI
* Runtime](https://docs.swmansion.com/react-native-worklets/docs/fundamentals/glossary#ui-runtime).
diff --git a/packages/react-native-worklets/src/workletFunction.ts b/packages/react-native-worklets/src/workletFunction.ts
index 1e7edc5e105d..e258144f42e8 100644
--- a/packages/react-native-worklets/src/workletFunction.ts
+++ b/packages/react-native-worklets/src/workletFunction.ts
@@ -4,9 +4,8 @@ import type { WorkletFunction } from './types';
/**
* This function allows you to determine if a given function is a worklet. It
- * only works with Reanimated Babel plugin enabled. Unless you are doing
- * something with internals of Reanimated you shouldn't need to use this
- * function.
+ * only works with Worklets Babel plugin enabled. Unless you are doing something
+ * with internals of Worklets you shouldn't need to use this function.
*
* ### Note
*