skills/react-native-best-practices/references/multithreading/SKILL.md
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.
npx skillsauth add software-mansion-labs/react-native-skills multithreadingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
Before answering any multithreading question, check that react-native-worklets is up to date:
package.json to find the installed react-native-worklets version.npm view react-native-worklets version to get the latest published version.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).
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)
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.
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, testing with Jest, feature flags, troubleshooting |
development
TypeGPU is type-safe WebGPU in TypeScript. Use whenever the user writes, debugs, or designs TypeGPU code: 'use gpu' shader functions, tgpu.fn, buffers, textures, bind groups, compute and render pipelines, vertex layouts, slots, accessors, and any TypeGPU API. Shader logic and CPU-side resources are tightly coupled - handle both sides here even if the user only mentions one (e.g. "how do I write a shader", "how do I create a buffer"). Trigger on any mention of typegpu, tgpu, "use gpu", TypedGPU, or WebGPU code written using TypeGPU's schema API (d.*, tgpu.*, std.*). Do NOT trigger for raw WebGPU (using GPUDevice/GPURenderPipeline directly without tgpu), WGSL-only questions, Three.js, Babylon.js, or WebGL.
tools
Best practices for integrating and using RNRepo — Software Mansion's infrastructure for pre-built React Native library artifacts that reduces native build times by up to 2×. Use when setting up, configuring, or troubleshooting RNRepo in a React Native or Expo project. Trigger on: 'RNRepo', 'rnrepo', 'slow builds', 'build times', 'prebuilt artifacts', 'prebuilt libraries', '@rnrepo/expo-config-plugin', '@rnrepo/build-tools', 'prebuilds-plugin', 'rnrepo.config.json', 'DISABLE_RNREPO', 'packages.rnrepo.org', 'Maven prebuild', 'CocoaPods prebuild', 'xcframework prebuild', 'prebuild AAR', 'build from source', 'native compilation slow', 'Gradle plugin slow', 'pod install slow', 'CI build times'.
development
Software Mansion's best practices for SVG rendering in React Native apps using React Native SVG. Use when rendering vector graphics, icons, charts, illustrations, or any SVG content. Trigger on: 'react-native-svg', 'SVG', 'vector graphics', 'render icon', 'draw shape', 'chart', 'path', 'Svg component', 'SvgUri', 'SvgXml', 'SvgCss', 'FilterImage', 'SVG filter', or any request to display scalable vector content in a React Native app.
tools
Software Mansion's best practices for rich text in React Native using react-native-enriched and react-native-enriched-markdown. Use when building rich text editors, formatted text inputs, Markdown renderers, or any feature requiring inline styling, mentions, links, structured text editing, or Markdown display. Trigger on: 'rich text editor', 'rich text input', 'text editor', 'react-native-enriched', 'react-native-enriched-markdown', 'EnrichedTextInput', 'EnrichedMarkdownText', 'formatted text input', 'WYSIWYG', 'mentions input', 'text formatting toolbar', 'markdown renderer', 'markdown display', 'render markdown', 'display markdown natively', 'LaTeX math', 'GFM tables', or any request to build rich text editing or Markdown rendering in React Native.