A react-native (or actually; Expo) app that compares react-native's Turbo Modules vs expo's Expo Modules vs @mrousavy's Nitro Modules.
This app specifically benchmarks the time it takes to call a synchronous function and return a result back to JS.
There are two synchronous functions per module:
addNumbers(a: number, b: number): numberaddStrings(a: string, b: string): string
For each module, I chose the recommended language for iOS - so the TurboModule is implemented in Objective-C, and both the Expo Module and Nitro Module are implemented in Swift.
The functions are run 100.000 times after a short timeout to make sure the JS VM isn't busy with any other scheduled microtasks, and the total execution time is measured with performance.now().
Nitro is an upcoming library/toolkit I have been working on because I hit a lot of limitations with my libraries (react-native-vision-camera, react-native-mmkv, react-native-filament, and so on).
I will use Nitro in my libraries to allow me to make them much faster than they already are, and to benefit from some fundamental differences such as it's instance-based approach. The Frame in VisionCamera, or MMKV in MMKV, or anything in Filament are all a C++ objects - I needed a better way of exposing those to JS, so I built Nitro.
I will make Nitro publicly available for everyone to build native C++, Swift or Kotlin modules with! 🔥
On my iPhone 15 Pro I got these numbers in a release build:
| ExpoModules | TurboModules | NitroModules | |
|---|---|---|---|
100.000x addNumbers(...) |
434.85 | 115.86ms | 7.27ms |
100.000x addStrings(...) |
429.53ms | 179.02ms | 29.94ms |
- For
addNumbers(...), Nitro Modules is 59x as fast as ExpoModules, and 15x as fast as TurboModules 🔥 - For
addStrings(...), Nitro Modules is 13x as fast as ExpoModules, and 5x as fast as TurboModules 🔥
On my Mac Studio (Apple M1 Max, 32GB RAM), I got these numbers in a release build ("designed for iPad"):
| ExpoModules | TurboModules | NitroModules | |
|---|---|---|---|
100.000x addNumbers(...) |
764.31ms | 195.12ms | 42.32ms |
100.000x addStrings(...) |
773.00ms | 308.65ms | 138.43ms |
In addition to platform-specific languages, NitroModules can be written in C++, a cross-platform language. C++ is a lot faster than platform-specific languages like Swift or Kotlin:
| NitroModules Swift | NitroModules C++ | |
|---|---|---|
100.000x addNumbers(...) |
8.21ms | 6.33ms |
100.000x addStrings(...) |
68.20ms | 12.99ms |
Note that these are just very specific benchmarks. They profile JS <-> Native function execution time (call, argument parsing, and result argument conversion). In an actual real world app, performance may vary.
Note: I put these benchmarks together in ~1 hour. My focus is on making Nitro Modules as fast as possible, but also as powerful as possible, so this is where my time is dedicated at. If I made any mistakes in the benchmark, please let me know so I can update it asap!
I don't intend to put Turbo or Expo modules in bad light here, they are insanely cool tools to build native modules.