{"id":13538393,"url":"https://github.com/mrousavy/react-native-multithreading","last_synced_at":"2025-04-08T04:12:36.389Z","repository":{"id":37730635,"uuid":"348082335","full_name":"mrousavy/react-native-multithreading","owner":"mrousavy","description":"🧵 Fast and easy multithreading for React Native using JSI","archived":false,"fork":false,"pushed_at":"2022-11-18T05:08:56.000Z","size":777,"stargazers_count":1148,"open_issues_count":23,"forks_count":53,"subscribers_count":18,"default_branch":"master","last_synced_at":"2025-04-01T03:31:46.110Z","etag":null,"topics":["js","jsi","multiprocessing","multithreading","native","react","react-native","thread","threading","threads","typescript","worklet"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mrousavy.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":"mrousavy","patreon":null,"open_collective":null,"ko_fi":"mrousavy","tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":null}},"created_at":"2021-03-15T18:33:44.000Z","updated_at":"2025-03-28T18:42:22.000Z","dependencies_parsed_at":"2022-06-29T22:33:24.350Z","dependency_job_id":null,"html_url":"https://github.com/mrousavy/react-native-multithreading","commit_stats":null,"previous_names":[],"tags_count":5,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-multithreading","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-multithreading/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-multithreading/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mrousavy%2Freact-native-multithreading/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mrousavy","download_url":"https://codeload.github.com/mrousavy/react-native-multithreading/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247773719,"owners_count":20993639,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["js","jsi","multiprocessing","multithreading","native","react","react-native","thread","threading","threads","typescript","worklet"],"created_at":"2024-08-01T09:01:11.380Z","updated_at":"2025-04-08T04:12:36.365Z","avatar_url":"https://github.com/mrousavy.png","language":"C++","readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"img/icon.png\" width=\"30%\"\u003e\n  \u003ch1\u003ereact-native-multithreading\u003c/h2\u003e\n  \u003ch3\u003e🧵 Fast and easy multithreading for React Native using JSI. 🧵\u003c/h3\u003e\n  \u003ch4\u003e\n    ⚠️ Note: This is a proof of concept. \u003cbr/\u003e\n    Do not use this library in production. \u003cbr/\u003e\u003cbr/\u003e\n    \u003ca href=\"https://github.com/mrousavy/react-native-vision-camera\"\u003eVisionCamera\u003c/a\u003e goes beyond this concept and \u003cbr/\u003e\n    use a separate JS runtime to provide an API for processing \u003cbr/\u003e\n    camera frames in realtime. Check out \u003ca href=\"https://mrousavy.com/react-native-vision-camera/docs/guides/frame-processors\"\u003eFrame Processors\u003c/a\u003e!\n  \u003c/h4\u003e\n  \u003cbr/\u003e\n  \u003ca align=\"center\" href='https://ko-fi.com/F1F8CLXG' target='_blank'\u003e\n    \u003cimg height='36' style='border:0px;height:36px;' src='https://az743702.vo.msecnd.net/cdn/kofi2.png?v=0' border='0' alt='Buy Me a Coffee at ko-fi.com' /\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003ca align=\"center\" href=\"https://github.com/mrousavy?tab=followers\"\u003e\n    \u003cimg src=\"https://img.shields.io/github/followers/mrousavy?label=Follow%20%40mrousavy\u0026style=social\" /\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003ca align=\"center\" href=\"https://twitter.com/mrousavy\"\u003e\n    \u003cimg src=\"https://img.shields.io/twitter/follow/mrousavy?label=Follow%20%40mrousavy\u0026style=social\" /\u003e\n  \u003c/a\u003e\n\u003c/div\u003e\n\u003cbr/\u003e\n\n## Installation\n\n```sh\nnpm install react-native-multithreading\nnpx pod-install\n```\n\nSince JSI is not officially released, installing **react-native-multithreading** requires you to edit a few native files. See [the setup guide (**SETUP.md**)](./SETUP.md) for more details.\n\n\u003e Requires react-native-reanimated [**2.1.0**](https://github.com/software-mansion/react-native-reanimated/releases/tag/2.1.0) or higher.\n\n\u003e 🎉 [v1.0](https://github.com/mrousavy/react-native-multithreading/releases/tag/1.0.0) with Android support is here! 🎉\n\n## Why\n\nSince [JSI](https://github.com/react-native-community/discussions-and-proposals/issues/91) is becoming more mainstream, there might be functions that are actually blocking and take a while to execute. For example, a storage library like [my react-native-mmkv](https://github.com/mrousavy/react-native-mmkv) or an SQLite JSI library might take a few milliseconds to execute a complex call. You don't want your entire React-JS thread to freeze when doing that, since users will perceive a noticeable lag or freeze.\n\nThat's where **react-native-multithreading** comes in; you can simply off-load such expensive calculations/blocking calls to a separate thread with almost no overhead while your main React-JS thread can concentrate on running your app's business logic, respond to user input, update state and more. You can also run complex JS calculations such as the [Fibonacci number](https://en.wikipedia.org/wiki/Fibonacci_number), but that's probably a rare use-case.\n\n\u003e Inspired by [**@karol-bisztyga**'s Multithreading PR for Reanimated](https://github.com/software-mansion/react-native-reanimated/pull/1561)\n\n## Usage\n\nTo try out the Fibonacci Example, clone the repo and run the following commands:\n\n```\nyarn bootstrap\ncd example\nyarn ios\n```\n\n\u003e See [my tweet 🐦](https://twitter.com/mrousavy/status/1371793888273432577)\n\n### Shoot and Forget\n\nTo simply perform an expensive calculation on another thread without caring about the result, use the `spawnThread` function:\n\n```ts\n// JS thread\nspawnThread(() =\u003e {\n  'worklet'\n  // custom thread\n  // expensive calculation\n})\n// JS thread\n```\n\nThe React-JS Thread will continue execution while the custom thread will run the given function on a custom parallel runtime.\n\n### Await\n\nSince `spawnThread` returns a `Promise`, you can also await the result. The React-JS Thread will not be blocked and will still be able to continue execution elsewhere (timers, callbacks, rendering, ...), while the custom thread runs the given function in a custom parallel runtime.\n\n```ts\nconst result = await spawnThread(() =\u003e {\n  'worklet'\n  // expensive calculation\n  return ...\n})\n```\n\n### Fibonacci\n\nThis example calculates the [Fibonacci Number](https://en.wikipedia.org/wiki/Fibonacci_number) for the given input. This demonstrates expensive calculation, awaiting the result, as well as using values from \"outside\". (`fibonacci` function and `input` are captured into the new thread and therefore immutable.)\n\n```ts\nconst fibonacci = (num: number): number =\u003e {\n  'worklet'\n  if (num \u003c= 1) return 1\n  return fibonacci(num - 1) + fibonacci(num - 2)\n}\n\nconst input = 50\nconst result = await spawnThread(() =\u003e {\n  'worklet'\n  console.log(`calculating fibonacci for input: ${input} in JS-Runtime: ${global._LABEL}...`)\n  const fib = fibonacci(input)\n  console.log(\"finished calculating fibonacci!\")\n  return fib\n})\nconsole.log(`Fibonacci Result: ${result}`)\n```\n\n## What's possible?\n\n* You can run any JavaScript code you want in there.\n* You can use variables from \"outside\" (e.g. state), but those will be immutable/frozen.\n* You can use functions from \"outside\".\n   - Worklets (functions with the `'worklet'` directive) can be called directly on the separate thread\n   - Native JSI functions (\"host functions\", aka functions that print `function f() { [native code] }` when you call `.toString()` on them) can be called synchronously (e.g. functions from [react-native-mmkv](https://github.com/mrousavy/react-native-mmkv#usage))\n   - Normal JS functions (e.g. setState) can be called on the React-JS thread with [`runOnJS`](https://docs.swmansion.com/react-native-reanimated/docs/api/runOnJS)\n* You can assign Reanimated Shared Values.\n\n\u003e Note that react-native-multithreading is more of a proof of concept than a production ready library. Everything works as I listed it here, but in real world app you most likely won't be needing a JS multithreading library.\n\n## What's not possible?\n\n1. Since the library uses JSI for synchronous native methods access, remote debugging (e.g. with Chrome) is no longer possible. Instead, you should use [Flipper](https://fbflipper.com).\n2. All functions you are calling inside a custom thread, must be workletized to truly run on a separate thread. So add the `'worklet'` directive at the top of every function you're calling in that thread (including the thread callback itself), and don't forget to install the Reanimated babel plugin.\n\n## Supported JS engines\n\n* JavaScript Core (JSC)\n* [Hermes](http://hermesengine.dev)\n* [V8](http://github.com/Kudo/react-native-v8) (iOS only)\n\n## Performance\n\nSince the worklets are completely dispatched in an isolated thread, nothing interrupts their execution.\n\nBe aware that there always will be a small overhead when calling `spawnThread`, because all variables from outside have to be copied into the new thread first. For example, if you use the separate thread to do complex array operations, be aware that the array has to be copied into the separate thread first. Always benchmark the performance differences!\n\n## Credits\n\n* [react-native-reanimated](http://github.com/software-mansion/react-native-reanimated) for Shared Value adapting, essentially allowing JSI multithreading\n* [**@karol-bisztyga**](https://github.com/karol-bisztyga) and [**@piaskowyk**](https://github.com/piaskowyk) for helping me understand a few parts of Reanimated better\n* [**@Szymon20000**](https://github.com/Szymon20000) for taking time to review and merge my Reanimated PRs\n* [JNI tips](https://developer.android.com/training/articles/perf-jni) and [fbjni](https://github.com/facebookincubator/fbjni) to make Android JNI interop easier\n* [**@iamyellow**](https://github.com/iamyellow) for being a huge help on the Android side\n* [Erik the Coder](https://www.erikthecoder.net/2019/03/30/async-does-not-imply-concurrent/) for the Icon\n* You, for appreciating my work\n\n\u003e Note: Technically this is not [multithreading](https://en.wikipedia.org/wiki/Multithreading_(computer_architecture)), but rather [multiprocessing](https://en.wikipedia.org/wiki/Multiprocessing).\n","funding_links":["https://github.com/sponsors/mrousavy","https://ko-fi.com/mrousavy","https://ko-fi.com/F1F8CLXG'"],"categories":["Uncategorized","C++"],"sub_categories":["Uncategorized"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrousavy%2Freact-native-multithreading","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmrousavy%2Freact-native-multithreading","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmrousavy%2Freact-native-multithreading/lists"}