We Built a Decompiler for React Native Apps. Here's How We Tested It at Insomnihack
React Native is everywhere. Instagram, Discord, Shopify, Walmart, thousands of enterprise apps. They all ship the same thing: a compiled Hermes bytecode bundle sitting in the APK's assets/ folder. If you've ever tried to reverse one of these, you know the pain.
You open the APK in JADX. You see a ReactActivity. You find index.android.bundle in the assets. You open it in a hex editor and see c6 1f bc 1e at offset 0. Congratulations, it's Hermes bytecode. Now what?
The Problem
Hermes is Meta's JavaScript engine for React Native. Instead of shipping JS source code that gets parsed at runtime (like V8 or JavaScriptCore), Hermes precompiles everything into bytecode during the build. The result is a .hbc file with a custom binary format: function tables, string tables, register-based opcodes, environment chains for closures. None of the original source code survives.
There was no public tool to properly decompile this. You had hbctool which could disassemble individual opcodes, but reading raw register-based assembly for thousands of functions is not realistic. JEB added some Hermes support, but it's expensive and closed-source. For most people, reversing a React Native app meant staring at bytecode mnemonics and reconstructing the logic in your head.
That's a problem when you're doing a security audit on a React Native app and the entire business logic lives in that bytecode bundle.
What We Did About It
Anthony Bondu, security researcher at Symbiotic Security, built hermes-decomp. It's a Rust-based decompiler that turns Hermes bytecode back into readable JavaScript. It's open-source. It's fast. It supports every Hermes bytecode version from 40 to 99.
https://github.com/SymbioticSec/hermes-decomp/
Here's what it does: you point it at an index.android.bundle (or any .hbc file), and it gives you back JavaScript. Not perfect source code, but readable, structured code with control flow recovery, constant propagation, closure resolution, and pattern detection for generators, async functions, and classes.
How It Works
The decompilation pipeline has five stages:
Parsing.The binary HBC file is parsed to extract headers, the string table, the function table, and raw bytecode. Hermes bytecode is register-based (not stack-based like JVM), so each instruction operates on named registers (
r0,r1, ...).Disassembly.Raw bytes are decoded into human-readable mnemonics.
0x3b 0x00 0x01becomesMov r0, r1. String references are resolved so you seeLoadConstString r3, "REVEAL FLAG"instead of raw string IDs.IR Lifting.This is where the real work happens. The bytecode is lifted into a high-level Intermediate Representation. Registers are mapped to variables. Jump targets are analyzed to build a Control Flow Graph (CFG). Environment chains are traced to resolve closure variables across function boundaries.
Analysis & Optimization.The IR goes through several passes: constant propagation (replacing register values with their known constants), copy propagation (eliminating redundant moves), dead code elimination, and structure recovery (turning jump graphs back into
if/else,while,for,try/catch). There's also pattern matching to detect generator state machines, async/await patterns, and class constructors.Code Generation.The optimized IR is emitted as JavaScript. The output is valid JS syntax that you can read, search, and analyze.
What You Can Do With It
Beyond decompile, the tool ships with: info (file metadata), disasm (raw bytecode), xref (cross-references to strings or functions), extract (split Metro modules into separate files), dump (export string/function tables), tui (interactive terminal browser with bin-diff split view), bin-diff (compare two HBC files), graphviz (control flow graph), modules/deps (Metro module registry and dependency tree), and closures (resolve what each closure_X maps to).
The Insomnihack Test
We needed real-world test cases. Insomnihack 2026 gave us exactly that.
Orange Cyberdefense Switzerland published two mobile reverse engineering challenges: so-AIRMES and !so-AIRMES. Both were React Native APKs shipping Hermes bytecode version 96. The first one had the crypto logic in a native C++ library. The second one had everything in JavaScript, with heavy obfuscation and custom crypto routines.
These were perfect test cases: real challenges, realistic app structure (10,000+ functions bundled with React Native framework code), and crypto logic that required actually understanding the decompiled output, not just pattern matching.
Click here to get the full so-AIRMES Writeup
Limitations :
hermes-decomp is not perfect. Some things to know:
Generator functions (async/await compiled to state machines) produce partial decompilation in some cases. The tool handles many generator patterns, but complex state machines sometimes need the disassembly view to fill in gaps.
Variable names are gone. Hermes strips all variable names in release builds. You get closure_0, tmp3, r10020 instead of setStatus, result, apiKey. The tool uses heuristics to name some things (like detecting React hooks), but it's fundamentally working with register numbers.
Not all Hermes opcodes are documented by Meta. The tool supports versions 40 through 99, but some exotic instructions in newer versions might not decompile cleanly.
Who This Is For :
Security auditors reviewing React Native applications
Reverse engineers analyzing mobile apps for malware or compliance
Bug bounty hunters looking at React Native targets
CTF players facing Hermes bytecode challenges
Developers debugging production bytecode issues
If you've ever opened a React Native APK and hit a wall at index.android.bundle, this tool gets you past it.
Get It
1. GitHub: https://github.com/SymbioticSec/hermes-decomp
1git clone <https://github.com/SymbioticSec/hermes-decomp.git>2cd hermes-decomp3cargo build --release
2. The tool also ships as an MCP server, so you can plug it directly into AI assistants (Claude, Cursor, etc.) for AI-assisted reverse engineering.
If you find something interesting with it, we'd love to hear about it. If you want to contribute rules, PRs are open.