Whether it’s a quick question or a detailed brief — we’d love to hear about it.
Technical Wins Newsletter
Chasing Two Map Bugs Below the JavaScript Bridge
On a navigation app we built for a client, custom pins started breaking in two unrelated ways at once.
Overview
The app crashed on iOS in 10 to 20 percent of sessions, and pin icons rendered wrong on Android. Neither problem lived in our code. Both were sitting inside react-native-maps itself, below where our own debugging usually stops. Here's how the team traced both bugs to their real source and fixed them without forking the library.
The Setup
Custom pins are the core visual feature of a navigation app we built for a client, so when they broke, they broke visibly. On iOS, the app was crashing in 10 to 20 percent of sessions. On Android, pins were rendering at the wrong size or position, sometimes cut off entirely. The first instinct was to assume the problem was ours, bad state handling, a timing issue in how pin data moved through the app. None of that held up. Frontend fixes didn’t touch the iOS crash rate at all.
The Insight
Both bugs lived inside react-native-maps itself, one level below where JavaScript stack traces could see. The fix meant reading native logs and native source code directly, not staring harder at our own code.
The Approach
Switching map libraries wasn’t realistic given the timeline, and forking react-native-maps long-term wasn’t something the team had the resources for. So the first move on iOS was switching layers entirely: instead of chasing the crash through JavaScript stack traces, the next step was opening Xcode and reading native logs. That’s where the real cause showed up. Null values in the pin data were reaching the native map view and crashing at the Objective-C level, and a related timing issue let internal view indexes drift out of bounds during fast mount and unmount cycles.
The fix needed two parts. JavaScript-side sanitization stopped null values from reaching the marker data in the first place. But some of the crash was happening purely inside native reconciliation, so the second part patched the native guard checks directly, adding a nil check and clamping the index to the array bounds instead of trusting it blindly.
Android had no shortcut waiting anywhere online, just an old forum post describing the same symptom with no fix attached. The cause turned out to be a bitmap sized off the parent view’s width and height before child views had finished laying out, so any custom icon built from nested views got measured too early and drawn cut off. Both fixes went in as patch-package diffs rather than a full fork, so they survive a fresh install and stay commented for whoever touches this code next.
The Results
The iOS crash rate dropped from 10 to 20 percent of sessions down to 0 percent after release. Android had no crash dashboard to confirm against since it was a rendering bug, so the team manually tested a range of icon shapes and screen densities until the rendering held up consistently.
The Lesson
Don’t stay in the layer you’re most comfortable in just because it’s comfortable. A lot of time went into optimizing frontend code for a bug that was actually happening in native code below the JavaScript bridge. The moment native logs got checked directly, the real cause on iOS turned up faster than everything tried before it.
A Quote
“The logs do not lie. Once I saw in Xcode that the crash was happening in native Objective-C code, no amount of JavaScript-side fixes alone was going to fully solve it. I did not want to stack a workaround on top of a bug, I wanted to actually fix the root cause.”