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.

News Technical Wins

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.”

GET STARTED

Tell us what you want to build.

Whether it’s a quick question or a detailed brief — we’d love to hear about it.

  • Honest assessment of whether we're the right fit
  • Fixed pricing, no hidden costs
  • 10+ years of trusted delivery
No sales pressure.
No lengthy process.
Just an honest conversation about technology.








    Thank you for contacting us!

    We'll be in touch with you shortly.