Bridging Data Types in React Native
The React Native bridge only moves serializable data, so values crossing between JS and native must be primitives, arrays, or plain objects. You face this building native modules. The footgun is passing functions or class instances; the bridge strips them.
WHY IT EXISTS: React Native runs JavaScript in a separate thread from the native UI and platform APIs. Because these two worlds use different memory heaps and languages, they cannot share objects directly. The bridge was created to marshal data across this boundary safely, but that requires converting everything into a format both sides can parse without shared pointers or memory models.
THE MENTAL MODEL: Think of the bridge as a JSON-only postal service. If you cannot write it in a JSON file, you cannot mail it. Functions, class instances, circular references, and binary blobs do not fit in the envelope. The sender serializes the payload, the post office queues it, and the receiver deserializes it back into dictionaries and arrays on the native side.
HOW IT WORKS: When JavaScript calls a native module method, the arguments are converted to a JSON-like representation. Booleans, numbers, and strings map directly to their native equivalents. Arrays become NSArray on iOS or ArrayList on Android, while plain objects become NSDictionary or HashMap. Promises and callbacks are not data types; they are replaced by bridge-managed IDs that let native code send a follow-up message later. Date objects are not automatically converted and usually arrive as null or invalid values unless you explicitly pass a timestamp number or ISO string. Null and undefined generally map safely, but optional arguments require careful handling on the native side to avoid type mismatches.
WHEN TO USE IT: You rely on these rules whenever you build a native module, write a TurboModule, or emit events from native to JavaScript. It also governs how you return results from native image pickers, Bluetooth LE scanners, or push notification handlers.
WHEN NOT TO USE IT: Do not use the bridge for high-frequency streaming data such as audio samples, camera frames, or gaming loops. The serialization and thread-hopping overhead will drop frames and burn battery. For those cases, use JSI, C++ shared memory, or native views that draw directly without round-tripping through JavaScript. Also avoid sending massive lists of objects across the bridge in a single batch; paginate or compress the payload to keep the UI responsive.
ONE CANONICAL EXAMPLE: A common task is returning a timestamp from native code. If the native side returns a Java Date or NSDate object, the bridge cannot serialize it and JavaScript receives null or crashes. The correct approach is to convert the date to a Unix timestamp number or an ISO 8601 string before crossing the bridge, then reconstruct a JavaScript Date on the other side. This pattern applies to any non-primitive type that lacks an automatic mapping.
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.