react-native-worklets
@amazon-devices/react-native-worklets is the React Native multithreading library that provides the foundation for Reanimated's performance capabilities. It allows you to run JavaScript code in parallel on multiple threads and runtimes, enabling smooth animations and interactions that don't block the main JavaScript thread.
What are Worklets?
Worklets are JavaScript functions that can be serialized and executed on different threads. When you mark a function with the 'worklet' directive, the Babel plugin transforms it into a serializable format that can be copied and run on the UI thread or other custom runtimes.
Key Features
- Multithreading: Execute JavaScript code on separate threads (UI thread, custom worklet runtimes)
- Zero-copy serialization: Efficiently transfer functions between threads without performance overhead
- Babel plugin integration: Automatically transforms marked functions into worklets
- Runtime creation: Create custom JavaScript runtimes for specialized workloads
- Seamless integration: Works transparently with Reanimated for animations and gestures
Documentation
Check out dedicated documentation page for info about this library, API reference and more: https://docs.swmansion.com/react-native-worklets/.
Installation
-
Add the JavaScript library dependency in the
package.jsonfile."dependencies": { ... "@amazon-devices/react-native-worklets": "~1.0.0" } - Add
@amazon-devices/react-native-worklets/pluginplugin to yourbabel.config.jsmodule.exports = { presets: [ ... // don't add it here :) ], plugins: [ ... '@amazon-devices/react-native-worklets/plugin', ], }; - Clear Metro bundler cache using
npm start -- --reset-cachecommand. - Reinstall
package-lock.jsonfile usingnpm installcommand. - If you'll need more detailed info, you could refer to the installation section of the external docs.
Examples
Demonstrates creating and using custom worklet runtimes for parallel processing
import React, { useState } from 'react';
import { Button, StyleSheet, View, Text } from 'react-native';
import { createWorkletRuntime, runOnRuntime, runOnJS } from '@amazon-devices/react-native-worklets';
/**
* Custom Worklet Runtime Example
* Demonstrates creating and using custom worklet runtimes for parallel processing
*/
export default function WorkletCustomRuntimeExample() {
const [result, setResult] = useState<string>('');
const handlePress = () => {
setResult('Processing...');
// Create a custom runtime with an initializer
const customRuntime = createWorkletRuntime('myCustomRuntime', () => {
'worklet';
console.log('Custom runtime initialized!');
});
// Run code on the custom runtime
runOnRuntime(customRuntime, () => {
'worklet';
console.log('Running on custom runtime');
// Perform heavy computation without blocking UI or JS thread
let sum = 0;
for (let i = 0; i < 1000000; i++) {
sum += i;
}
const result = `Computation complete! Sum: ${sum}`;
console.log(result);
runOnJS(setResult)(result);
})();
};
return (
<View style={styles.container}>
<Text style={styles.title}>Custom Worklet Runtime</Text>
<Text style={styles.description}>
Creates an isolated JavaScript runtime for specialized workloads.
{'\n\n'}
This allows heavy computations to run in parallel without blocking the UI or JS thread.
</Text>
<Button title="Run on Custom Runtime" onPress={handlePress} />
{result && <Text style={styles.result}>{result}</Text>}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
justifyContent: 'center',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 12,
},
description: {
fontSize: 14,
color: '#666',
marginBottom: 20,
lineHeight: 20,
},
result: {
marginTop: 20,
fontSize: 16,
color: '#007AFF',
fontWeight: '500',
},
});
Thread switching example
import React, { useState } from 'react';
import { Button, StyleSheet, View, Text, ScrollView } from 'react-native';
import { runOnUI, runOnJS } from '@amazon-devices/react-native-worklets';
/**
* Thread Switching Example
* Demonstrates switching between JavaScript and UI threads
*/
export default function WorkletThreadSwitchExample() {
const [log, setLog] = useState<string[]>([]);
const addLog = (message: string) => {
setLog(prev => [...prev, message]);
};
const handlePress = () => {
setLog([]);
// Start on JS thread
addLog('1. Starting on JS thread');
// Switch to UI thread
runOnUI(() => {
'worklet';
console.log('2. Now on UI thread');
runOnJS(addLog)('2. Now on UI thread');
// Do some work on UI thread
const sum = Array.from({ length: 100 }, (_, i) => i).reduce((a, b) => a + b, 0);
console.log('3. Computed sum on UI thread:', sum);
runOnJS(addLog)(`3. Computed sum: ${sum}`);
// Call back to JS thread
runOnJS(addLog)('4. Back on JS thread');
})();
};
return (
<View style={styles.container}>
<Text style={styles.title}>Thread Switching</Text>
<Text style={styles.description}>
Demonstrates switching between JavaScript and UI threads using runOnUI and runOnJS.
</Text>
<Button title="Switch Threads" onPress={handlePress} />
{log.length > 0 && (
<ScrollView style={styles.logContainer}>
{log.map((entry, index) => (
<Text key={index} style={styles.logEntry}>{entry}</Text>
))}
</ScrollView>
)}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
padding: 20,
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 12,
},
description: {
fontSize: 14,
color: '#666',
marginBottom: 20,
lineHeight: 20,
},
logContainer: {
marginTop: 20,
maxHeight: 300,
padding: 12,
backgroundColor: '#f5f5f5',
borderRadius: 8,
},
logEntry: {
fontSize: 14,
color: '#333',
marginVertical: 4,
},
});
APIs
Worklets library on Vega provides comprehensive APIs for multithreading, memory management, and utility functions.
Threading
| Method | Description |
|---|---|
createWorkletRuntime |
Creates a new JS runtime for running worklets on separate threads |
runOnUI |
Asynchronously runs workletized functions on the UI thread (deprecated) |
runOnUIAsync |
Asynchronously runs workletized functions on the UI thread and returns a Promise |
runOnUISync |
Synchronously runs workletized functions on the UI thread and returns the result |
runOnJS |
Asynchronously runs non-workletized functions on the JS thread (deprecated) |
runOnRuntime |
Runs workletized functions on a custom worklet runtime (deprecated) |
scheduleOnRN |
Schedules a worklet to run on the React Native (JS) thread |
scheduleOnUI |
Schedules a worklet to run on the UI thread |
callMicrotasks |
Processes all pending microtasks in the current runtime |
executeOnUIRuntimeSync |
Synchronously executes code on the UI runtime (deprecated) |
Memory
| Method | Description |
|---|---|
createSerializable |
Creates a serializable object that can be passed between different JavaScript Runtimes |
createSynchronizable |
Creates a new Synchronizable holding the provided initial value |
isSerializableRef |
Checks if a value is a serializable reference |
isSynchronizable |
Asserts whether a value is a Synchronizable |
Synchronizable |
Serializable is a type of shared memory that holds an immutable value that can be serialized and deserialized across different JavaScript Runtimes |
makeShareable |
Makes a value shareable across threads (deprecated) |
makeShareableCloneRecursive |
Recursively clones and makes a value shareable (deprecated) |
makeShareableCloneOnUIRecursive |
Recursively clones and makes a value shareable on UI thread (deprecated) |
Utility
| Method | Description |
|---|---|
getRuntimeKind |
Returns the kind of runtime currently executing (1=JS, 2=UI, 3=Worker) |
isWorkletFunction |
Checks if a function is a worklet |
Exceptions on Vega
Worklets library on Vega has a few exceptions in terms of API support. This section will go over those exceptions.
- Feature flags are currently not supported on Vega
- Bundle Mode is currently not supported on Vega
Supported versions
| NPM package version | Vega SDK version | Vega OS version | React Native version |
|---|---|---|---|
| ~1.0.0 | 0.24 | OS 1.2 (2101020054720) |
0.83 |
Credits
This project has been built and is maintained thanks to the support from Shopify, Expo.io and Software Mansion
Last updated: Jul 13, 2026

