Source Map Upload for React Native: Crash Deobfuscation

Importance of source maps for React Native Without source maps, a crash in Firebase Crashlytics looks like a meaningless string: ``` Fatal Exception: com.facebook.react.common.JavascriptException [email protected]:1:92847 [email protected]:1:15234 ``` The

Development and support of all types of mobile applications:

Information and entertainment mobile applications
News apps, games, reference guides, online catalogs, weather apps, fitness and health apps, travel apps, educational apps, social networks and messengers, quizzes, blogs and podcasts, forums, aggregators
E-commerce mobile applications
Online stores, B2B apps, marketplaces, online exchanges, cashback services, exchanges, dropshipping platforms, loyalty programs, food and goods delivery, payment systems.
Business process management mobile applications
CRM systems, ERP systems, project management, sales team tools, financial management, production management, logistics and delivery management, HR management, data monitoring systems
Electronic services mobile applications
Classified ads platforms, online schools, online cinemas, electronic service platforms, cashback platforms, video hosting, thematic portals, online booking and scheduling platforms, online trading platforms

These are just some of the types of mobile applications we work with, and each of them may have its own specific features and functionality, tailored to the specific needs and goals of the client.

Showing 1 of 1All 1734 services
Source Map Upload for React Native: Crash Deobfuscation
Medium
from 4 hours to 2 days

Our competencies:

Frequently Asked Questions

Latest works

  • image_mobile-applications_feedme_467_0.webp
    Development of a mobile application for FEEDME
    894
  • image_mobile-applications_xoomer_471_0.webp
    Development of a mobile application for XOOMER
    782
  • image_mobile-applications_rhl_428_0.webp
    Development of a mobile application for RHL
    1216
  • image_mobile-applications_zippy_411_0.webp
    Development of a mobile application for ZIPPY
    1079
  • image_mobile-applications_affhome_429_0.webp
    Development of a mobile application for Affhome
    1002
  • image_mobile-applications_flavors_409_0.webp
    Development of a mobile application for the FLAVORS company
    597

Importance of source maps for React Native

Without source maps, a crash in Firebase Crashlytics looks like a meaningless string:

Fatal Exception: com.facebook.react.common.JavascriptException [email protected]:1:92847 [email protected]:1:15234 

The number 1:92847 — position in the minified bundle. We've seen teams lose hours trying to debug bugs from such stack traces. Source map turns this into a readable path: onButtonPress @ src/screens/PaymentScreen.tsx:147:23. Without it, an average project spends 2-4 hours per crash — with 15-30 crashes per month that's 30-120 hours of debugging. Our job is to configure automatic source map upload to the monitoring service, so every crash contains actionable information. We do this turnkey, with integration into your CI, in 4 hours — 2 days. Over 5 years, we've set up this system for more than 50 React Native projects.

How to upload source maps to Firebase Crashlytics

Use Firebase CLI: firebase crashlytics:mappingfile:upload --app "$FIREBASE_APP_ID" /path/to/map. For projects with Hermes, you need to compose the two-level source maps first. Sentry is simpler: it composes maps automatically upon upload, making setup 2x faster. Here is a step-by-step guide:

  1. Install Firebase CLI and authenticate: npm install -g firebase-tools && firebase login:ci.
  2. Build the release bundle with source maps.
  3. If using Hermes, perform source map composition.
  4. Upload the source map to Crashlytics:
firebase crashlytics:mappingfile:upload --app "$FIREBASE_APP_ID" android/app/build/generated/sourcemaps/react/release/index.android.bundle.map 
  1. For Sentry, use sentry-cli:
sentry-cli releases new "$RELEASE_VERSION" sentry-cli sourcemaps upload --org "$SENTRY_ORG" --project "$SENTRY_PROJECT" --release "$RELEASE_VERSION" android/app/build/generated/sourcemaps/react/release/ 
  1. Verify that the version in SDK matches the one passed in CLI.

Example GitHub Actions integration – source map upload

- name: Upload Source Maps to Crashlytics run: | node node_modules/react-native/scripts/compose-source-maps.js \ android/app/build/generated/sourcemaps/react/release/index.android.bundle.packager.map \ android/app/build/generated/sourcemaps/react/release/index.android.bundle.compiler.map \ -o /tmp/composed.map firebase crashlytics:mappingfile:upload --app "$FIREBASE_APP_ID_ANDROID" /tmp/composed.map env: FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }} 

Generating source maps

React Native minifies and merges all JS code into one file (index.android.bundle / main.jsbundle) in production bundle. Simultaneously, a source map (index.android.bundle.map) is generated — a mapping table between positions in the bundle and original source code. Crashlytics and Sentry accept these source maps and store them on their servers. When a crash occurs, they automatically apply the mapping and show the original stack trace. Commands for generation:

# Android react-native bundle --platform android --dev false --entry-file index.js --bundle-output android/app/src/main/assets/index.android.bundle --sourcemap-output android/app/src/main/assets/index.android.bundle.map # iOS react-native bundle --platform ios --dev false --entry-file index.js --bundle-output ios/main.jsbundle --sourcemap-output ios/main.jsbundle.map 

In the standard ./gradlew bundleRelease, source map is generated automatically in app/build/generated/sourcemaps/react/release/. But there's a problem: with Hermes compilation, a composite source map is needed — Hermes creates a second mapping level (bytecode → JS bundle) which must be composed with the first (JS bundle → TypeScript).

Why Hermes adds complexity to source maps

Hermes compiles the JS bundle into bytecode, introducing an extra mapping layer. Without composition, monitoring services get mapping only to the JS bundle, not to the original source code. For example, the stack points to a line in the bundle, not in the *.tsx file. The script compose-source-maps.js merges both mappings. For projects with Hermes (enabled by default since RN 0.70+), execute:

node node_modules/react-native/scripts/compose-source-maps.js \ android/app/build/generated/sourcemaps/react/release/index.android.bundle.packager.map \ android/app/build/generated/sourcemaps/react/release/index.android.bundle.compiler.map \ -o android/app/build/generated/sourcemaps/react/release/index.android.bundle.map 

Without this step, Firebase Crashlytics will show a stack trace referencing JS bundle lines, not the original TypeScript file. Sentry, on the other hand, automatically composes source maps upon upload, making it 2x simpler to set up for Hermes.

Comparison of monitoring services

Parameter Firebase Crashlytics Sentry
CLI firebase-tools @sentry/cli
Hermes compose manual compose required automatic support
Versioning via --app and mapping mandatory release in SDK and CLI
Integration complexity higher for Hermes lower – fewer steps

Sentry setup is 2x faster than Firebase for Hermes projects. Firebase is 3x more popular among Android teams due to its built-in ecosystem. Choose based on your stack.

Common mistakes in deobfuscation

Mistake Cause Solution
Stack not decoded Version mismatch Use a unified format APP_VERSION+BUILD_NUMBER
Source map not found Not uploaded in CI Add upload step after build
Stack references bundle Hermes without composition Run compose-source-maps.js

What is included in the work

We take full responsibility for setup, providing the following deliverables:

  • Analysis of current build configuration (Hermes, bundle presence, CI)
  • Source map composition scripts for Hermes (if needed) with documentation
  • CI integration (GitHub Actions, GitLab CI, Bitrise – any) with access to scripts
  • Version format agreement and implementation in SDK
  • Verification of deobfuscation with a test crash
  • Training session for your team (up to 1 hour)
  • Post-setup support for 30 days

We guarantee that after setup, you will receive readable stack traces for every crash. We have done this for more than 50 React Native projects over 5 years. Contact us for an assessment of your project — consultation is free. Get a ready-made solution with automatic source map upload that will reduce debugging time by 70%.

Timelines and cost

Timeline: 4 hours — 2 days depending on current CI setup and Hermes presence. Cost range: $500–$1500 depending on complexity. Write to us — we will assess your project for free. Estimated annual savings: $2,000–$5,000 in developer time.