◉RORK LABJP
●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…●GPT-6.1 SOL — Added to Rork's model menu (09-29) with Low, Medium and High effort; included on Pro and Max●SONNET 5.5 — Claude Sonnet 5.5 is selectable: strong at UI design and faster than Sonnet 5 (09-28)●SDK 58 — Beta since 09/15 with no stable date yet; running projects in Expo Go has required login since 09/03●WIDGET — A write-up traces an iOS widget that renders black only in production builds●OBSERVE — EAS Observe now records native crashes too (SDK 57.0.21 or later, 10/07)●NEW — My App Open Ad Only Showed When the App…
Articles/Dev Tools
⬡ Dev Tools/2026-05-27Intermediate

Two Months of Rork × Hermes in Production — Cold Start and Memory in Real Numbers

What actually happens to cold start, memory, and crash rates after running Rork-generated apps with Hermes enabled in production for two months. Field notes from an indie developer with 50 million cumulative downloads.

Rork585Hermes9React Native239Cold StartMemory5Field Notes

I have been shipping mobile apps as an indie developer since 2014, and the apps under my account have accumulated more than 50 million downloads. At that scale, the balance between startup time and memory is directly tied to AdMob revenue. An app that feels heavy in the first second loses the user before the first ad ever appears, and that gap shows up in the dashboard the next morning.

Over the past two months I have been running three apps rebuilt from Rork templates with Hermes enabled in production. There are plenty of tutorial-style write-ups about switching the engine, but it is surprisingly hard to find honest two-month-later notes. So I am leaving mine here.

The Setup and the Devices I Measured

The three apps are all on Expo SDK 53 with jsEngine: "hermes" in app.json, which is the default. As a baseline I kept the Firebase Performance Monitoring and Crashlytics dashboards from the JSC (JavaScriptCore) era, so the before-and-after numbers come from the same instrumentation, not a fresh harness.

I measured on four devices that sit on my desk: iPhone 13, iPhone 15 Pro, Pixel 7, and the second-generation iPhone SE. The reason I keep an older device in the loop is that more than forty percent of installs across my 50 million downloads still come from phones that are at least three years old. Judging an indie app only on a flagship is a quick way to misread the field.

The collection script is a small in-house logger that combines the app launch timestamp from expo-application with react-native-performance marks. I took ten sessions per device per day for twenty-eight days and used the median, which smooths out the occasional cold-system spike.

Cold Start: A Thirty-Eight Percent Cut, with Caveats

In the JSC era the average cold start was 2.4 seconds on the SE and 0.9 seconds on the iPhone 15 Pro. After two weeks of bedding-in on Hermes, those numbers moved to 1.6 seconds and 0.55 seconds. That is a thirty-three percent improvement on the SE, thirty-nine percent on the 15 Pro, and a thirty-eight percent average.

The headline number feels good, but the breakdown is more sober. The bytecode precompilation that Hermes is famous for only covers the region from "native bridge ready" to "first render." In my apps that region accounts for about sixty percent of total startup. The remaining forty percent is the AdMob SDK initializing, Firebase booting, and RevenueCat restoring purchases. None of that shrinks because of Hermes.

So the realistic expectation is "a roughly fifty percent cut in five-to-six-tenths of the budget." You need to pair Hermes with lazy initialization for ad and billing SDKs to feel a difference users would actually notice. As someone whose monthly AdMob revenue depends on this, every second shaved off cold start lifts my first-ad reach rate by four to six percentage points.

Memory: An Eighteen Percent Drop on the Pixel 7

The memory side surprised me on Android. The resident-set size on the Pixel 7 after returning from the home screen dropped from a JSC-era mean of 142 MB to 116 MB — roughly eighteen percent. iPhone improvements were smaller, in the eight to ten percent range.

My read is that the Hermes heap model meshes well with the Android Runtime's generational GC. The concrete payoff in my catalog was that a long-standing crash class — "background restart due to memory pressure" on the Pixel 7 — fell from twenty-three issues over two months to just three. A backlog that I had been triaging in Crashlytics simply quieted down after the engine swap.

On lower-spec Android devices (the Pixel 3a, older Galaxy A models), the rate of white-screen-on-resume also fell from eleven percent under JSC to about four percent. The most accurate way to describe the change is that the OS now has a little more headroom before it decides to kill the process.

Crash-Free Rate and the Pitfalls I Hit

Crash-free sessions moved from 99.4 percent to 99.7 percent. That is mostly a side effect of fewer memory crashes rather than Hermes itself being more stable.

There are pitfalls worth mentioning, because I burned half a day on the first one. Hermes uses a different source map lineage than JSC, and for the first few days Sentry showed me stack traces full of mystery function names. You need to bake "upload the Hermes symbol map produced by hermesc" into Step 0 of your release pipeline, otherwise production debugging effectively stalls.

The second one is Intl. The output of toLocaleString("ja-JP", ...) differs subtly between JSC and older Hermes builds — at one point my eCPM and pricing displays lost their thousands separators. The version of Hermes bundled with Expo SDK 53 fixes this, but if you are mixing in projects on SDK 51 or earlier, watch the formatting in your live screens carefully.

What Two Months Taught Me

The honest conclusion after two months is that Hermes is not a "make-it-fast switch." It is structural work that tidies up memory and startup. To turn that into something users feel, you still need to sequence ad and billing SDKs deliberately, lazy-load images, and design your splash screen so it stops being a delay.

Even so, the Android memory side moved the dial in places that matter. About sixty percent of my 50 million downloads sit on Android, and Day 1 retention on the migrated apps lifted by two points. In AdMob's monthly eCPM terms, that lands as a five to eight percent uplift — small per user, meaningful across the catalog.

The next thing I want to try is shrinking the bytecode payload when shipping through EAS Update OTA. I am reworking transformer.minifierPath in metro.config.js to see if I can take another fifteen percent off the delivered size. I will write up that result in a month. If you are running Rork with Hermes in production too, I hope these notes save you a few hours.

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 $10 for lifetime access
View Membership →

If you found this article helpful, a small tip ($1.50) would mean a lot to us. Your support helps keep this site ad-free and covers server and hosting costs.

Related Articles

⬡ Dev Tools2026-10-13
Before You Ship: Go Looking for Your Own Keys Inside the Exported Expo Bundle
A key can be missing from your source and still be sitting inside the finished app. I ran expo export on Expo SDK 57, searched the bundle with grep and a short Node script, and recorded which secrets show up and which don't.
⬡ Dev Tools2026-09-04
EAS secret visibility does not keep a value out of your app — deciding prefix and visibility separately
The EXPO_PUBLIC_ prefix decides what ships inside your app; EAS visibility decides who can read it. Why stacking them blanks a value on OTA updates, and how to check your build.
⬡ Dev Tools2026-08-27
Count your worklets before you start deleting your own code
Hermes V1 attaches 512KB of debug metadata to every worklet, so simply importing Reanimated can add tens of megabytes. Here are the three numbers to count before blaming your own code, and how to choose between the four available fixes.