/multithreading
Software Mansion's best practices for multithreading in React Native apps using react-native-worklets. Use when running JavaScript on multiple threads, offloading heavy computation from the JS thread, communicating between runtimes, or sharing data across threads. Trigger on:
$ npx -y skills add software-mansion-labs/skills --skill multithreading --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/multithreading
Context preview
The summary Claude sees to decide when to auto-load this skill.
Software Mansion's best practices for multithreading in React Native apps using react-native-worklets. Use when running JavaScript on multiple threads, offloading heavy computation from the JS thread, communicating between runtimes, or sharing data across threads. Trigger on:
SKILL.md
multithreading.SKILL.mdname: multithreading
description: "Software Mansion's best practices for multithreading in React Native apps using react-native-worklets. Use when running JavaScript on multiple threads, offloading heavy computation from the JS thread, communicating between runtimes, or sharing data across threads. Trigger on: 'worklet', 'worklets', 'react-native-worklets', 'runOnUI', 'runOnJS', 'scheduleOnUI', 'scheduleOnRN', 'scheduleOnRuntime', 'createWorkletRuntime', 'background thread', 'UI thread', 'worker runtime', 'Serializable', 'Synchronizable', 'multithreading', 'parallel execution', 'offload computation', 'background processing', 'Bundle Mode', or any request to move work off the JS thread in a React Native app."
React Native Multithreading with Worklets
Software Mansion's production multithreading patterns for React Native using `react-native-worklets`.
React Native Worklets lets you run JavaScript code in parallel across multiple threads and runtimes. It powers Reanimated, Gesture Handler, and Skia under the hood.
Version Check
Before answering any multithreading question, check that `react-native-worklets` is up to date:
1. Read the user's `package.json` to find the installed `react-native-worklets` version. 2. Run `npm view react-native-worklets version` to get the latest published version. 3. If the installed version is older than the latest, inform the user and recommend upgrading before proceeding with implementation advice.
Runtime Model
React Native apps have three kinds of runtimes. Picking the right target is the first decision:
What does the work need?
├── Respond to native events or drive animations on the same frame?
│ └── UI Runtime (main thread, one per app)
├── Heavy computation, data processing, or background tasks?
│ └── Worker Runtime (custom thread, many per app)
└── Access React state, navigation, or RN APIs?
└── RN Runtime (JS thread, one per app)Runtimes do not share memory. Data crosses runtime boundaries through serialization (immutable copies) or Synchronizable (shared mutable state).
API Decision Tree
Need to run code on a different runtime?
├── Fire-and-forget (no return value needed)?
│ ├── Target is UI Runtime → scheduleOnUI(fn, ...args)
│ ├── Target is RN Runtime → scheduleOnRN(fn, ...args)
│ └── Target is Worker → scheduleOnRuntime(runtime, fn, ...args)
├── Need the return value asynchronously (Promise)?
│ ├── Target is UI Runtime → await runOnUIAsync(fn, ...args)
│ └── Target is Worker → await runOnRuntimeAsync(runtime, fn, ...args)
└── Need the return value synchronously (blocks caller)?
├── Target is UI Runtime → runOnUISync(fn, ...args)
└── Target is Worker → runOnRuntimeSync(runtime, fn, ...args)Critical Rules
**The `'worklet'` directive**: functions that run on Worklet Runtimes must be workletized. Add `'worklet';` as the first statement in the function body. Callbacks passed to `scheduleOnUI`, `scheduleOnRuntime`, and similar APIs are autoworkletized by the Babel plugin.
function computeOnUI() {
'worklet';
return 2 + 2;
}**Don't call scheduling APIs from the wrong runtime**: `scheduleOnUI`, `runOnUISync`, `runOnUIAsync`, `runOnRuntimeSync`, `runOnRuntimeAsync`, `scheduleOnRuntime` can only be called from the RN Runtime (unless Bundle Mode is enabled). Calling them from a Worklet Runtime throws an error.
**Closures are copied, not shared**: when a worklet runs on a different runtime, its closure variables are serialized at invocation time. Mutating the original variable after scheduling has no effect on the worklet's copy.
**Deprecated APIs**: `runOnUI` is replaced by `scheduleOnUI`. `runOnJS` is replaced by `scheduleOnRN`. `runOnRuntime` is replaced by `scheduleOnRuntime`. The new APIs pass arguments directly instead of returning a curried function.
References
Load at most one reference file per question.
| File | Load when question is about | |------|------------------------------| | `threading-api.md` | Scheduling work across runtimes, creating Worker Runtimes, sync vs async execution, migrating from deprecated APIs | | `shared-memory.md` | Passing data between runtimes, closures in worklets, Serializable, Synchronizable, shared mutable state | | `setup-and-advanced.md` | Installing worklets, Babel plugin config, Bundle Mode usage, import forwarding, testing with Jest, feature flags, troubleshooting |
For enabling Bundle Mode in an app (babel option, metro config, mandatory metro/metro-runtime patches, "Failed to get the SHA-1" errors), use the dedicated sub-skill instead: `../enable-worklets-bundle-mode/SKILL.md`.
Read more
name: multithreading description: "Software Mansion's best practices for multithreading in React Native apps using react-native-worklets. Use when running JavaScript on multiple threads, offloading heavy computation from the JS thread, communicating between runtimes, or sharing data across threads. Trigger on: 'worklet', 'worklets', 'react-native-worklets', 'runOnUI', 'runOnJS', 'scheduleOnUI', 'scheduleOnRN', 'scheduleOnRuntime', 'createWorkletRuntime', 'background thread', 'UI thread', 'worker runtime', 'Serializable', 'Synchronizable', 'multithreading', 'parallel execution', 'offload computation', 'background processing', 'Bundle Mode', or any request to move work off the JS thread in a React Native app."
React Native Multithreading with Worklets
Software Mansion's production multithreading patterns for React Native using `react-native-worklets`.
React Native Worklets lets you run JavaScript code in parallel across multiple threads and runtimes. It powers Reanimated, Gesture Handler, and Skia under the hood.
Version Check
Before answering any multithreading question, check that `react-native-worklets` is up to date:
1. Read the user's `package.json` to find the installed `react-native-worklets` version. 2. Run `npm view react-native-worklets version` to get the latest published version. 3. If the installed version is older than the latest, inform the user and recommend upgrading before proceeding with implementation advice.
Runtime Model
React Native apps have three kinds of runtimes. Picking the right target is the first decision:
What does the work need?
├── Respond to native events or drive animations on the same frame?
│ └── UI Runtime (main thread, one per app)
├── Heavy computation, data processing, or background tasks?
│ └── Worker Runtime (custom thread, many per app)
└── Access React state, navigation, or RN APIs?
└── RN Runtime (JS thread, one per app)Runtimes do not share memory. Data crosses runtime boundaries through serialization (immutable copies) or Synchronizable (shared mutable state).
API Decision Tree
Need to run code on a different runtime?
├── Fire-and-forget (no return value needed)?
│ ├── Target is UI Runtime → scheduleOnUI(fn, ...args)
│ ├── Target is RN Runtime → scheduleOnRN(fn, ...args)
│ └── Target is Worker → scheduleOnRuntime(runtime, fn, ...args)
├── Need the return value asynchronously (Promise)?
│ ├── Target is UI Runtime → await runOnUIAsync(fn, ...args)
│ └── Target is Worker → await runOnRuntimeAsync(runtime, fn, ...args)
└── Need the return value synchronously (blocks caller)?
├── Target is UI Runtime → runOnUISync(fn, ...args)
└── Target is Worker → runOnRuntimeSync(runtime, fn, ...args)Critical Rules
**The `'worklet'` directive**: functions that run on Worklet Runtimes must be workletized. Add `'worklet';` as the first statement in the function body. Callbacks passed to `scheduleOnUI`, `scheduleOnRuntime`, and similar APIs are autoworkletized by the Babel plugin.
function computeOnUI() {
'worklet';
return 2 + 2;
}**Don't call scheduling APIs from the wrong runtime**: `scheduleOnUI`, `runOnUISync`, `runOnUIAsync`, `runOnRuntimeSync`, `runOnRuntimeAsync`, `scheduleOnRuntime` can only be called from the RN Runtime (unless Bundle Mode is enabled). Calling them from a Worklet Runtime throws an error.
**Closures are copied, not shared**: when a worklet runs on a different runtime, its closure variables are serialized at invocation time. Mutating the original variable after scheduling has no effect on the worklet's copy.
**Deprecated APIs**: `runOnUI` is replaced by `scheduleOnUI`. `runOnJS` is replaced by `scheduleOnRN`. `runOnRuntime` is replaced by `scheduleOnRuntime`. The new APIs pass arguments directly instead of returning a curried function.
References
Load at most one reference file per question.
| File | Load when question is about | |------|------------------------------| | `threading-api.md` | Scheduling work across runtimes, creating Worker Runtimes, sync vs async execution, migrating from deprecated APIs | | `shared-memory.md` | Passing data between runtimes, closures in worklets, Serializable, Synchronizable, shared mutable state | | `setup-and-advanced.md` | Installing worklets, Babel plugin config, Bundle Mode usage, import forwarding, testing with Jest, feature flags, troubleshooting |
For enabling Bundle Mode in an app (babel option, metro config, mandatory metro/metro-runtime patches, "Failed to get the SHA-1" errors), use the dedicated sub-skill instead: `../enable-worklets-bundle-mode/SKILL.md`.
Software Mansion's set of skills for AI-assisted React Native development.
Repo: software-mansion-labs/skills
Other skills on software-mansion-labs-skills.
- /detour-onboarding
Complete onboarding guide for developers who are new to Detour, the open-source deferred deep linking SDK by Software Mansion. Use this skill whenever a user asks what Detour is, how to get started with Detour, how to set up deep linking with Detour, how to install the Detour
Open skill - /migrate-to-detour
Use when the user mentions migrating deep links, switching away from Branch or AppsFlyer, replacing their deep linking SDK, setting up Detour deep linking for the first time, or asks how Branch/AppsFlyer concepts map to Detour. Covers the complete migration end to end - Detour
Open skill - /expo-horizon
Software Mansion's guide for migrating Expo SDK apps to Meta Quest using expo-horizon packages. Use when adding Meta Quest or Meta Horizon OS support to an existing Expo or React Native project. Trigger on: Meta Quest, Horizon OS, Quest 2, Quest 3, Quest 3S, VR app,
Open skill - /fishjam
Software Mansion's Fishjam — hosted WebRTC platform for video, audio, and one-to-many livestreaming. MUST USE before writing, reviewing, or debugging ANY code that talks to a Fishjam instance from a backend (Node, Python) or a client (React web, React Native / Expo). Routes to
Open skill - /js-server-sdk
Node.js / TypeScript server SDK for Fishjam — backends that create rooms, mint peer tokens, listen to server notifications, and run agents. Use when writing a Node.js / Express / Fastify / Hono / NestJS backend that talks to Fishjam, sets up a webhook receiver, runs an AI agent,
Open skill - /platform
Fishjam platform fundamentals — domain model and auth shared by all SDKs. Covers glossary (room, peer, track, agent, streamer, viewer), the four room types (conference / audio_only / livestream / audio_only_livestream), two-tier auth (management vs peer tokens), Sandbox vs
Open skill

