You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
High-performance columnar `ArrayBuffer` transport from JSI C++ to JavaScript.
5
+
Zero-copy columnar `ArrayBuffer` transport from JSI C++ to JavaScript.
6
6
7
-
JSI modules often return large datasets as arrays of objects. That is easy to use, but expensive at scale: every row becomes a JS object, every value is boxed, and the result puts pressure on the GC.
8
-
9
-
`react-native-columnar` writes fixed-width native values into one binary columnar buffer and exposes it to JS as typed array views (`Int32Array`, `Float64Array`, etc.). No per-row objects, no parsing, and no payload copy.
7
+
JSI modules often return datasets as arrays of objects — every row becomes a JS object, every value gets boxed, GC pressure grows. `react-native-columnar` packs all values into one binary buffer and exposes each column as a typed array view over the same memory. No objects, no parsing, no copy.
10
8
11
9
---
12
10
13
-
## Best use cases
14
-
15
-
- SQLite result sets
16
-
- Frame processor outputs
17
-
- Sensor streams
18
-
- Analytics events
19
-
- Game / physics data
20
-
- Large JSI payloads
21
-
- Realtime charts
22
-
23
-
---
11
+
## ⚡ Benchmark
24
12
25
-
## Benchmark
26
-
27
-
**Test:** 10 000 iterations — each call transfers N rows (5 columns) from C++ to JS and reads one row.
13
+
10 000 iterations · 5 columns · iPhone 16 Pro
28
14
29
15
```
30
-
Schema: id (int32) | status (uint8) | isActive (uint8) | createdAt (double) | updatedAt (double)
31
-
Iterations: 10 000
16
+
id (int32) | status (uint8) | isActive (uint8) | createdAt (double) | updatedAt (double)
**Array of objects** — each call allocates a JS array of objects with 5 keys each, boxes every value, and puts pressure on the GC — multiplied across 10 000 iterations.
42
-
43
-
**react-native-columnar** — one binary buffer is allocated in C++, all rows are written in a single loop, and the buffer pointer is handed to the JS engine as an `ArrayBuffer`. The JS side creates five typed array views (`Int32Array`, `Uint8Array`, `Float64Array`) over the same memory — **zero copies, zero parsing, no per-row object allocation**.
44
-
45
-
> Measured on iPhone 16 Pro. Results will vary by device and data shape.
46
-
47
26
---
48
27
49
-
## Requirements
28
+
## 🎯 Best use cases
50
29
51
-
- React Native with JSI native modules
52
-
- C++20 or newer (`std::span` is used by the C++ helper)
53
-
- iOS via CocoaPods or Android via CMake
54
-
- Fixed-width numeric data (`int8_t`, `uint32_t`, `double`, etc.)
30
+
SQLite result sets · Frame processor outputs · Sensor streams · Analytics events · Realtime charts · Large JSI payloads
Autolinking does not run in library projects. Use `add_subdirectory` instead — it resolves headers directly from `node_modules` without needing a Gradle dependency.
61
+
**Android — standalone library**
94
62
95
-
Make sure `NODE_MODULES_DIR` is passed from your `build.gradle` (any JSI library already does this):
`react-native-columnar` is optimized for dense numeric payloads. It does not encode
277
-
strings, nested objects, nullable values, or variable-length fields by itself.
278
-
279
-
For those cases, keep metadata separately or encode it into fixed-width columns
280
-
with your own conventions, such as enum ids, offsets, masks, or sentinel values.
186
+
Designed for dense numeric data only. Strings, nullable values, nested objects, and variable-length fields are not supported natively — encode them as fixed-width columns using ids, offsets, or sentinel values.
281
187
282
188
---
283
189
284
-
## Troubleshooting
285
-
286
-
### `react-native-columnar.h` not found
287
-
288
-
Make sure the package is added to your native build and linked to your JSI library.
289
-
290
-
On Android, check that Prefab is enabled in the Gradle module that builds your
291
-
native target:
292
-
293
-
```groovy
294
-
android {
295
-
buildFeatures {
296
-
prefab true
297
-
}
298
-
}
299
-
```
300
-
301
-
Then make sure CMake finds and links the Prefab package:
0 commit comments