home / skills / sovranbitcoin / sovran / animation-with-worklets
This skill helps you schedule cross-thread work in React Native using worklets guidelines, improving animation performance and thread safety.
npx playbooks add skill sovranbitcoin/sovran --skill animation-with-workletsReview the files below or copy the command above to add this skill to your agents.
---
name: animation-with-worklets
description: Provides React Native Worklets guidelines for scheduling functions between JS and UI threads. Applies to tasks involving scheduleOnRN, scheduleOnUI, worklets, thread scheduling, useAnimatedReaction, gesture handlers, or cross-thread function calls.
---
# Worklet Scheduling
## Overview
Guidelines for scheduling functions between JavaScript and UI threads using React Native Worklets. This skill covers when and how to use `scheduleOnRN` and `scheduleOnUI`, proper function definition patterns, and avoiding unnecessary worklet directives.
## When to Apply
Reference these guidelines when:
- Scheduling functions to run on UI thread from JS thread
- Calling JS thread functions from UI thread worklets
- Working with `useAnimatedReaction` or gesture handlers
- Batching shared value updates
- Implementing cross-thread communication in animations
## Key Guidelines
### Don't Use 'worklet' Directive Unless Explicitly Asked
**Never use the `"worklet"` directive unless explicitly requested.** In 99.9% of cases, there is no need to use it. `scheduleOnUI` handles worklet conversion automatically, so the directive is unnecessary. This also applies to gesture detector callbacks - you don't need to add the `"worklet"` directive in gesture handler callbacks.
### Use scheduleOnRN and scheduleOnUI Instead of runOnJS and runOnUI
Use `scheduleOnRN` and `scheduleOnUI` from `react-native-worklets` instead of `runOnJS` and `runOnUI` from `react-native-reanimated`.
**Don't do this:**
```tsx
import { runOnJS, runOnUI } from "react-native-reanimated";
```
**Instead, do this:**
```tsx
import { scheduleOnRN, scheduleOnUI } from "react-native-worklets";
```
### Type Definitions
```tsx
function scheduleOnRN<Args extends unknown[], ReturnValue>(
fun:
| ((...args: Args) => ReturnValue)
| RemoteFunction<Args, ReturnValue>
| WorkletFunction<Args, ReturnValue>,
...args: Args
): void;
function scheduleOnUI<Args extends unknown[], ReturnValue>(
fun: (...args: Args) => ReturnValue,
...args: Args
): void;
```
## Usage Patterns
### Always Define Functions Outside Using useCallback
Both `scheduleOnRN` and `scheduleOnUI` follow the same usage pattern: **always define the function outside using `useCallback` and pass the function reference** (not inline arrow functions).
**When to use:**
- `scheduleOnRN`: Call JavaScript thread functions from UI thread worklets (like in `useAnimatedReaction`, gesture handlers, or `useAnimatedStyle`)
- `scheduleOnUI`: Schedule functions to run on the UI thread
**Don't do this** – inline arrow function:
```tsx
// ❌ scheduleOnRN with inline function
useAnimatedReaction(
() => currentIndex.get(),
(nextIndex) => {
scheduleOnRN(() => {
setState(newValue);
});
}
);
// ❌ scheduleOnUI with inline function
scheduleOnUI(() => {
scale.set(withSpring(1.2));
});
```
**Instead**, do this – define function outside:
```tsx
// ✅ scheduleOnRN - JS thread function
const updateState = useCallback(() => {
setState(newValue);
}, [dependencies]);
useAnimatedReaction(
() => currentIndex.get(),
(nextIndex) => {
scheduleOnRN(updateState); // pass function reference
}
);
// ✅ scheduleOnUI - UI thread function
const updateAnimations = useCallback(() => {
scale.set(withSpring(1.2));
opacity.set(withSpring(0.8));
}, []);
scheduleOnUI(updateAnimations); // pass function reference
```
### Passing Arguments
Arguments are passed directly (not as an array) using rest parameter syntax:
```tsx
// Single argument
const updateState = useCallback((newValue: number) => {
setState(newValue);
}, []);
scheduleOnRN(updateState, newValue); // ✅ correct
// Multiple arguments
const handleUpdate = useCallback((index: number, value: string) => {
setState({ index, value });
}, []);
scheduleOnRN(handleUpdate, index, value); // ✅ correct - pass directly, not as array
scheduleOnUI(handleUpdate, index, value); // ✅ same pattern for scheduleOnUI
```
## Common Use Cases
### scheduleOnRN Use Cases
- React state setters (`setState`, `setExtendedSlides`, etc.)
- API calls or side effects
- Video player controls (`pause`, `resume`, `seek`)
- Haptic feedback
- Navigation functions
**Example:**
```tsx
// scheduleOnRN example
const pause = useCallback(() => {
videoPlayerRef.current?.pause();
}, []);
useAnimatedReaction(
() => isDragging.get(),
(current) => {
if (current) {
scheduleOnRN(pause);
}
}
);
```
### scheduleOnUI Use Cases
- Batch multiple shared value updates in the same frame
- UI thread worklet operations
**Example:**
```tsx
// scheduleOnUI example - batch updates
const batchUpdates = useCallback(() => {
scale.set(withSpring(1.2));
opacity.set(withSpring(0.8));
}, []);
scheduleOnUI(batchUpdates);
```
## Benefits
- **Automatic Worklet Conversion**: `scheduleOnUI` handles worklet conversion automatically
- **Better Performance**: Batching updates reduces UI thread overhead
- **Type Safety**: Better TypeScript support with proper type definitions
- **Cleaner Code**: No need for `"worklet"` directive in most cases
- **Consistent API**: Unified approach for cross-thread communication
This skill provides concise React Native Worklets guidelines for scheduling functions between JavaScript and UI threads. It explains when to use scheduleOnRN and scheduleOnUI, recommended function-definition patterns, and how to avoid unnecessary worklet directives. The guidance targets animation, gesture handlers, and cross-thread communication in mobile apps.
The skill inspects common scheduling patterns and recommends using scheduleOnRN and scheduleOnUI from react-native-worklets instead of runOnJS/runOnUI. It enforces defining callback functions outside of inline handlers (typically with useCallback) and passing references plus direct arguments. It also advises against using the "worklet" directive except when explicitly required because scheduleOnUI performs conversion automatically.
Do I need to add the "worklet" directive to my scheduled functions?
No. Avoid the "worklet" directive unless explicitly required. scheduleOnUI will handle conversion in almost all cases.
Should I ever use inline arrow functions with scheduleOnRN/scheduleOnUI?
No. Inline functions break memoization patterns and can cause unnecessary re-registrations. Define functions outside (useCallback) and pass the reference.