0
# Worklet Functions
1
2
Functions for executing code on the UI thread and managing worklet runtimes, enabling high-performance animations and computations that run independently of the JavaScript thread.
3
4
**IMPORTANT**: These functions are deprecated in React Native Reanimated and users should import them directly from `react-native-worklets` instead. They are re-exported here for compatibility but may be removed in future versions.
5
6
## Capabilities
7
8
### Thread Execution Control
9
10
Functions to execute code on different threads for optimal performance.
11
12
```typescript { .api }
13
/**
14
* Executes a worklet function on the UI thread
15
* @deprecated Import directly from react-native-worklets instead
16
* @param worklet - Function to execute on UI thread (must be a worklet)
17
* @returns Function that can be called from JS thread to trigger UI execution
18
*/
19
function runOnUI<Args extends readonly unknown[], Return>(
20
worklet: WorkletFunction<Args, Return>
21
): (...args: Args) => void;
22
23
/**
24
* Executes a JavaScript function on the JS thread from a worklet
25
* @deprecated Import directly from react-native-worklets instead
26
* @param jsFunction - JavaScript function to execute on JS thread
27
* @returns Worklet function that can be called from UI thread
28
*/
29
function runOnJS<Args extends readonly unknown[], Return>(
30
jsFunction: (...args: Args) => Return
31
): WorkletFunction<Args, void>;
32
33
/**
34
* Executes a worklet on a specific runtime
35
* @deprecated Import directly from react-native-worklets instead
36
* @param runtime - Target worklet runtime
37
* @param worklet - Worklet function to execute
38
* @returns Function to trigger execution on the specified runtime
39
*/
40
function runOnRuntime<Args extends readonly unknown[], Return>(
41
runtime: WorkletRuntime,
42
worklet: WorkletFunction<Args, Return>
43
): (...args: Args) => void;
44
```
45
46
**Usage Examples:**
47
48
```typescript
49
import React from "react";
50
import Animated, {
51
useSharedValue,
52
useAnimatedStyle,
53
runOnUI,
54
runOnJS,
55
withTiming
56
} from "react-native-reanimated";
57
import { Button } from "react-native";
58
59
const WorkletExample = () => {
60
const progress = useSharedValue(0);
61
62
// Function to run on JS thread
63
const logProgress = (value: number) => {
64
console.log(`Animation progress: ${value}`);
65
};
66
67
// Worklet function (runs on UI thread)
68
const animateWithLogging = (targetValue: number) => {
69
'worklet';
70
progress.value = withTiming(targetValue, { duration: 1000 }, (finished) => {
71
'worklet';
72
if (finished) {
73
// Call JS function from worklet using runOnJS
74
runOnJS(logProgress)(targetValue);
75
}
76
});
77
};
78
79
// UI thread computation worklet
80
const complexCalculation = (input: number): number => {
81
'worklet';
82
// Heavy computation that runs on UI thread
83
let result = input;
84
for (let i = 0; i < 1000; i++) {
85
result = Math.sin(result) * Math.cos(result) + input;
86
}
87
return result;
88
};
89
90
const animatedStyle = useAnimatedStyle(() => {
91
// Using complex calculation in worklet context
92
const computedValue = complexCalculation(progress.value);
93
94
return {
95
opacity: progress.value,
96
transform: [
97
{ scale: 1 + progress.value * 0.5 },
98
{ rotate: `${computedValue * 360}deg` }
99
],
100
};
101
});
102
103
// Run worklet on UI thread
104
const handlePress = () => {
105
runOnUI(animateWithLogging)(progress.value === 0 ? 1 : 0);
106
};
107
108
// Alternative: direct worklet call
109
const handleDirectCall = () => {
110
animateWithLogging(Math.random());
111
};
112
113
return (
114
<>
115
<Button title="Animate with Logging" onPress={handlePress} />
116
<Button title="Random Animation" onPress={handleDirectCall} />
117
118
<Animated.View
119
style={[
120
{
121
width: 100,
122
height: 100,
123
backgroundColor: "lightblue",
124
borderRadius: 10,
125
margin: 20,
126
},
127
animatedStyle,
128
]}
129
/>
130
</>
131
);
132
};
133
```
134
135
### Runtime Management
136
137
Create and manage custom worklet runtimes for specialized execution contexts.
138
139
```typescript { .api }
140
/**
141
* Creates a new worklet runtime with optional name
142
* @deprecated Import directly from react-native-worklets instead
143
* @param name - Optional name for the runtime (for debugging)
144
* @returns New WorkletRuntime instance
145
*/
146
function createWorkletRuntime(name?: string): WorkletRuntime;
147
148
/**
149
* Executes a worklet synchronously on the UI runtime
150
* @deprecated Import directly from react-native-worklets instead
151
* @param worklet - Worklet function to execute
152
* @returns Return value from the worklet execution
153
*/
154
function executeOnUIRuntimeSync<T>(worklet: () => T): T;
155
156
interface WorkletRuntime {
157
/** Runtime identifier */
158
__workletRuntimeId: number;
159
}
160
```
161
162
**Usage Examples:**
163
164
```typescript
165
import React, { useEffect, useState } from "react";
166
import Animated, {
167
createWorkletRuntime,
168
runOnRuntime,
169
executeOnUIRuntimeSync,
170
useSharedValue
171
} from "react-native-reanimated";
172
173
const RuntimeExample = () => {
174
const [result, setResult] = useState<number>(0);
175
const [customRuntime, setCustomRuntime] = useState<WorkletRuntime | null>(null);
176
const sharedCounter = useSharedValue(0);
177
178
useEffect(() => {
179
// Create custom runtime
180
const runtime = createWorkletRuntime("CustomCalculationRuntime");
181
setCustomRuntime(runtime);
182
183
return () => {
184
// Runtime cleanup would happen here if needed
185
};
186
}, []);
187
188
// Heavy computation worklet for custom runtime
189
const heavyComputation = (iterations: number): number => {
190
'worklet';
191
let result = 0;
192
for (let i = 0; i < iterations; i++) {
193
result += Math.sqrt(i) * Math.sin(i / 100);
194
}
195
return result;
196
};
197
198
// Worklet for UI runtime
199
const updateCounter = () => {
200
'worklet';
201
sharedCounter.value += 1;
202
return sharedCounter.value * 2;
203
};
204
205
const runCustomCalculation = () => {
206
if (customRuntime) {
207
// Run heavy computation on custom runtime
208
runOnRuntime(customRuntime, (iterations: number) => {
209
'worklet';
210
const result = heavyComputation(iterations);
211
// Cannot directly update state from worklet, need runOnJS
212
runOnJS(setResult)(result);
213
})(10000);
214
}
215
};
216
217
const runSyncCalculation = () => {
218
// Execute synchronously on UI runtime
219
const result = executeOnUIRuntimeSync(updateCounter);
220
setResult(result);
221
};
222
223
return (
224
<>
225
<Button title="Run Custom Runtime Calculation" onPress={runCustomCalculation} />
226
<Button title="Run Sync UI Calculation" onPress={runSyncCalculation} />
227
228
<Text>Result: {result}</Text>
229
<Text>Counter: {sharedCounter.value}</Text>
230
</>
231
);
232
};
233
```
234
235
### Worklet Utilities
236
237
Utility functions for working with worklets and shareable values.
238
239
```typescript { .api }
240
/**
241
* Checks if a value is a worklet function
242
* @deprecated Import directly from react-native-worklets instead
243
* @param value - Value to check
244
* @returns True if the value is a worklet function
245
*/
246
function isWorkletFunction(value: unknown): boolean;
247
248
/**
249
* Creates a deep shareable clone of a value for cross-thread usage
250
* @deprecated Import directly from react-native-worklets instead
251
* @param value - Value to make shareable
252
* @returns Shareable clone of the value
253
*/
254
function makeShareableCloneRecursive<T>(value: T): T;
255
```
256
257
**Usage Examples:**
258
259
```typescript
260
import React from "react";
261
import Animated, {
262
isWorkletFunction,
263
makeShareableCloneRecursive,
264
useSharedValue,
265
runOnUI
266
} from "react-native-reanimated";
267
268
const WorkletUtilsExample = () => {
269
const sharedValue = useSharedValue(0);
270
271
// Regular function
272
const regularFunction = (x: number) => x * 2;
273
274
// Worklet function
275
const workletFunction = (x: number) => {
276
'worklet';
277
return x * 2;
278
};
279
280
// Complex object to share
281
const complexData = {
282
numbers: [1, 2, 3, 4, 5],
283
config: {
284
duration: 1000,
285
easing: "ease-in-out",
286
},
287
compute: (value: number) => value * Math.PI,
288
};
289
290
const checkFunctions = () => {
291
console.log("Regular function is worklet:", isWorkletFunction(regularFunction));
292
console.log("Worklet function is worklet:", isWorkletFunction(workletFunction));
293
};
294
295
const shareComplexData = () => {
296
// Make complex data shareable across threads
297
const shareableData = makeShareableCloneRecursive(complexData);
298
299
runOnUI((data) => {
300
'worklet';
301
// Can safely use shareableData on UI thread
302
const result = data.numbers.reduce((sum, num) => sum + num, 0);
303
console.log("Sum calculated on UI thread:", result);
304
})(shareableData);
305
};
306
307
// Example of sharing configuration objects
308
const animationConfig = makeShareableCloneRecursive({
309
spring: {
310
damping: 15,
311
stiffness: 150,
312
},
313
timing: {
314
duration: 800,
315
easing: "ease-out",
316
},
317
});
318
319
const useSharedConfig = () => {
320
runOnUI((config) => {
321
'worklet';
322
// Use shared configuration on UI thread
323
sharedValue.value = withSpring(1, config.spring);
324
})(animationConfig);
325
};
326
327
return (
328
<>
329
<Button title="Check Function Types" onPress={checkFunctions} />
330
<Button title="Share Complex Data" onPress={shareComplexData} />
331
<Button title="Use Shared Config" onPress={useSharedConfig} />
332
</>
333
);
334
};
335
```
336
337
### Advanced Worklet Patterns
338
339
Complex worklet usage patterns and best practices.
340
341
**Performance-Optimized Worklets:**
342
343
```typescript
344
import React from "react";
345
import Animated, {
346
useSharedValue,
347
useAnimatedStyle,
348
useDerivedValue,
349
runOnUI,
350
runOnJS
351
} from "react-native-reanimated";
352
353
const AdvancedWorkletExample = () => {
354
const touches = useSharedValue<Array<{x: number, y: number}>>([]);
355
const canvasSize = useSharedValue({ width: 300, height: 300 });
356
357
// Heavy computation worklet
358
const processGestureData = useDerivedValue(() => {
359
'worklet';
360
const touchArray = touches.value;
361
362
if (touchArray.length < 2) return null;
363
364
// Calculate center point
365
const centerX = touchArray.reduce((sum, touch) => sum + touch.x, 0) / touchArray.length;
366
const centerY = touchArray.reduce((sum, touch) => sum + touch.y, 0) / touchArray.length;
367
368
// Calculate distances for scaling
369
const distances = touchArray.map(touch =>
370
Math.sqrt(Math.pow(touch.x - centerX, 2) + Math.pow(touch.y - centerY, 2))
371
);
372
373
const averageDistance = distances.reduce((sum, dist) => sum + dist, 0) / distances.length;
374
375
return {
376
center: { x: centerX, y: centerY },
377
scale: Math.max(0.5, Math.min(3, averageDistance / 100)),
378
rotation: Math.atan2(touchArray[1].y - touchArray[0].y, touchArray[1].x - touchArray[0].x)
379
};
380
});
381
382
// Optimized animation worklet
383
const animatedStyle = useAnimatedStyle(() => {
384
const gestureData = processGestureData.value;
385
386
if (!gestureData) {
387
return { opacity: 0.5 };
388
}
389
390
return {
391
opacity: 1,
392
transform: [
393
{ translateX: gestureData.center.x - canvasSize.value.width / 2 },
394
{ translateY: gestureData.center.y - canvasSize.value.height / 2 },
395
{ scale: gestureData.scale },
396
{ rotate: `${gestureData.rotation}rad` },
397
],
398
};
399
});
400
401
// Batched UI updates worklet
402
const batchedUpdates = (updates: Array<() => void>) => {
403
'worklet';
404
// Batch multiple updates for better performance
405
updates.forEach(update => update());
406
};
407
408
const handleMultipleUpdates = () => {
409
runOnUI(batchedUpdates)([
410
() => {
411
'worklet';
412
touches.value = [
413
{ x: Math.random() * 300, y: Math.random() * 300 },
414
{ x: Math.random() * 300, y: Math.random() * 300 },
415
];
416
},
417
() => {
418
'worklet';
419
canvasSize.value = {
420
width: 300 + Math.random() * 100,
421
height: 300 + Math.random() * 100
422
};
423
},
424
]);
425
};
426
427
return (
428
<>
429
<Button title="Update Gesture Data" onPress={handleMultipleUpdates} />
430
431
<Animated.View
432
style={[
433
{
434
width: 100,
435
height: 100,
436
backgroundColor: "lightcoral",
437
borderRadius: 10,
438
},
439
animatedStyle,
440
]}
441
/>
442
</>
443
);
444
};
445
```
446
447
**Error Handling in Worklets:**
448
449
```typescript
450
const errorHandlingWorklet = (value: number) => {
451
'worklet';
452
try {
453
// Risky operation
454
const result = complexCalculation(value);
455
return result;
456
} catch (error) {
457
// Handle errors in worklet context
458
runOnJS(console.error)('Worklet error:', error);
459
return 0; // Fallback value
460
}
461
};
462
```
463
464
## Type Definitions
465
466
```typescript { .api }
467
type WorkletFunction<Args extends readonly unknown[], Return> =
468
((...args: Args) => Return) & { __workletHash?: number };
469
470
interface WorkletRuntime {
471
__workletRuntimeId: number;
472
}
473
474
type ShareableRef<T> = {
475
value: T;
476
} & { __reanimatedShareableRef: true };
477
478
// Utility types for worklet context
479
type WorkletContext = {
480
_WORKLET: boolean;
481
_IS_WORKLET_RUNTIME: boolean;
482
};
483
484
// Shareable value constraints
485
type Shareable<T> = T extends Function
486
? WorkletFunction<any[], any>
487
: T extends object
488
? { [K in keyof T]: Shareable<T[K]> }
489
: T;
490
```
491
492
## Best Practices
493
494
### Worklet Performance Tips
495
496
1. **Minimize JS-UI thread communication**: Avoid frequent `runOnJS` calls
497
2. **Use derived values**: Compute dependent values on the UI thread
498
3. **Batch operations**: Group multiple updates together
499
4. **Cache expensive calculations**: Store results in shared values when possible
500
5. **Profile performance**: Use timing measurements to identify bottlenecks
501
502
### Common Pitfalls
503
504
1. **Closures in worklets**: Be careful with captured variables
505
2. **Async operations**: Worklets are synchronous, avoid async/await
506
3. **External dependencies**: Don't reference non-worklet functions directly
507
4. **Memory leaks**: Clean up event listeners and runtimes properly
508
5. **Error handling**: Always handle potential errors in worklets