◉RORK LABJP
●GPT6.1 — GPT-6.1 Sol joined the Rork model menu (Sep 29). It is the latest entry on the changelog●10/12 — 7 days left until React Native 0.88.x is due. Expo SDK 58 stable is only described as early October●NEW — Multiseat Purchases Are Already On: Decide Whether to Keep Them Before October 22●SDK 58 — A fix PR (#50998) for npm install failing in new projects is under review. No stable date has been given yet●SONNET — Claude Sonnet 5.5 is now in Rork (Sep 28). It is described as over 30% faster than Sonnet 5●iOS 27 — From April 2027, App Store uploads require the iOS 27 SDK. There is time to update your build environment calmly●GPT6.1 — GPT-6.1 Sol joined the Rork model menu (Sep 29). It is the latest entry on the changelog●10/12 — 7 days left until React Native 0.88.x is due. Expo SDK 58 stable is only described as early October●NEW — Multiseat Purchases Are Already On: Decide Whether to Keep Them Before October 22●SDK 58 — A fix PR (#50998) for npm install failing in new projects is under review. No stable date has been given yet●SONNET — Claude Sonnet 5.5 is now in Rork (Sep 28). It is described as over 30% faster than Sonnet 5●iOS 27 — From April 2027, App Store uploads require the iOS 27 SDK. There is time to update your build environment calmly
Articles/Dev Tools
⬡ Dev Tools/2026-06-28Advanced

When your Rork app's production crashes arrive minified — wiring Hermes source maps and debug IDs into Sentry

Rork-generated Expo apps run on Hermes, so production crashes often arrive as index.bundle:1:284913 with no function names. Here is how to wire Hermes source maps and debug IDs into Sentry so your stack traces become readable.

Rork575Expo212Sentry6Hermes8Source MapsCrash Reporting

✦ Premium Article

The first crash that reached Sentry after a release was a single line: index.android.bundle:1:284913. No repro steps, no screen name, nothing. The React Native (Expo) app that Rork generated for me runs on Hermes, and the production bundle is minified into one line. The crash was captured, but unreadable — the most frustrating state to be in.

If you run apps as an indie developer for any length of time, the unreadable stack trace is a wall you hit at least once. Across the apps I run at Dolice, the native side is symbolicated through Crashlytics and dSYMs, but the Rork-based Expo apps work through a completely different mechanism. The keys are the Hermes source map and the debug ID that ties it to a specific build. Get those right, and the same crash view comes back with function names and original line numbers.

Why Hermes only sends you numbers

Hermes does not run your JavaScript as-is. At build time it precompiles it into Hermes bytecode (.hbc). On top of that, the production build has Metro concatenate every module into a single file and shorten variable names. Line 42 of your PaywallScreen.tsx becomes "column 284913" of one enormous collapsed line.

What the device sends on a crash is only that collapsed position. The lookup table that maps it back to the original file and line is the source map — and with Hermes you need a Hermes-specific compose step on top of the regular source map. Skip it and you fall into the trap of "uploading source maps" that never actually symbolicate.

Debug IDs guarantee "this is the same build"

When symbolication breaks even though you uploaded source maps, the cause is almost always that the bundle that crashed and the source map you uploaded came from different builds. Tying them together by version name (like 1.8.0) falls apart the moment you ship a hotfix.

Debug IDs solve this at the root. A debug ID is a unique identifier generated per build and baked into both the bundle and its source map. Sentry matches the debug ID inside the crash against the debug ID of an uploaded source map, so it no longer depends on version names lining up. Modern @sentry/react-native makes this the default. Since switching from version matching to this approach myself, missed symbolication has dropped to nearly zero.

✦

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
✦If you've been stuck with crashes that read index.bundle:1:284913, you'll get a crash view with real function names and line numbers today
✦You'll bake the same Hermes debug ID into both the EAS Build output and its source map, so a tiny version drift never breaks symbolication again
✦You'll symbolicate OTA (EAS Update) crashes too, so even a few-thousand-download production app lets you start triage within 5 minutes
Secure payment via Stripe · Cancel anytime
✦

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Rork Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • ✦Copy-paste ready implementation code
  • ✦New advanced guides published daily
  • ✦$5/mo or $15 for lifetime access
View Membership →

Related Articles

⬡ Dev Tools2026-09-21
A build that stops with exit code 0 — the flag that silenced the log, and the check that let an empty file through
Two reports landed in the same week: eas build --local stopping with exit code 0 but produced no further output, and a zero-byte stub that never got embedded. Both came down to settings that reduce output. Here is how to audit your own scripts.
⬡ Dev Tools2026-09-07
Adding .easignore stops EAS from reading .gitignore — count what actually ships to the build
EAS Build decides what to upload from .gitignore, and the moment you add .easignore the two swap places. Here is how I count the bundled files before sending, plus a measured result: once a parent directory is excluded, an exclamation mark cannot bring a file back.
⬡ Dev Tools2026-09-05
Your Widget Extension Can Submit a BGTaskScheduler Request. It Just Cannot Register the Handler
Calling BGTaskScheduler from a widget extension compiles, submits, and returns true — and then nothing runs. Here is why registration belongs to the host app only, and how I moved refresh ownership back where it belongs across my wallpaper apps.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links