React Native's Hermes engine compiles your JavaScript to Hermes bytecode, shipped as an HBC bundle inside the app, and while that is harder to read than a plaintext JavaScript bundle, it is not obfuscation and it is not protection. HBC is a documented binary bytecode format, so disassemblers and decompilers such as hbctool and hermes-dec can turn it back toward readable logic, and the strings it contains, including any hardcoded secret, remain directly extractable. The defensive takeaway is that shipping as Hermes bytecode does not hide anything you would not want an attacker to see, so analyze your own app's bundle to know what is recoverable, and never rely on Hermes to conceal secrets or logic.
Short answer
Hermes bytecode is recoverable, so treat it as no protection for secrets or logic. The Hermes engine compiles JavaScript ahead of time to bytecode in the HBC format, and per the Hermes project that format is a defined binary, so tools like hbctool disassemble and reassemble it and other tools decompile it toward pseudo-JavaScript. Strings, including embedded secrets, are extractable directly. Per the OWASP MASVS, secrets must not live in the client, because compiled clients are reverse-engineerable. Analyze your own app's HBC bundle to see what is exposed, keep secrets on a backend, and do not treat Hermes compilation as a security measure.
What the HBC format is
HBC is the Hermes bytecode format, the compiled output the Hermes engine produces from your React Native JavaScript. Instead of shipping your JavaScript as readable text, which is what a standard React Native bundle does, Hermes compiles it ahead of time into bytecode that its virtual machine executes, and that bytecode travels inside your app as an HBC file. It is a binary format rather than source, which is why a Hermes app looks opaque compared to a plaintext bundle at first glance.
The important detail is that HBC is a defined, versioned format, not an encrypted or secret one. Its bytecode version changes across Hermes releases, and the structure of the format is understood, which is exactly what makes tooling able to parse it. So while HBC is not human-readable the way source is, it is not a black box either: it is a documented instruction set that a parser can walk through. That property is the entire reason decompilers and disassemblers for it exist, and it is what separates a higher bar from an actual protection.
Decompiler and disassembler tools
Several tools work with Hermes bytecode, and hbctool is the one most people mean. hbctool is a utility that disassembles an HBC file into a readable assembly-like representation and can reassemble it, which is used to inspect and even patch the bytecode of a Hermes app. Because it targets specific bytecode versions, it works against the HBC versions it supports, and it is the common starting point for anyone examining a Hermes bundle.
Beyond hbctool, decompilers such as hermes-dec aim to reconstruct pseudo-JavaScript from the bytecode, producing output closer to the original logic than raw disassembly, and assembler-disassembler projects like hasmer serve similar analysis purposes. The official Hermes toolchain also includes utilities that can dump bytecode. The point of naming these is not to provide a reverse-engineering recipe but to show that mature tooling exists, which is what a defender needs to understand: recovering logic and strings from a Hermes bundle is a solved, tool-supported task, not a barrier that stops a determined analyst.
Why Hermes is not obfuscation
It is worth stating plainly, because the assumption is common: compiling to Hermes bytecode is not obfuscation and does not protect your code. Obfuscation deliberately transforms code to make its logic hard to follow even when readable; Hermes simply compiles to a different, non-text format for performance and startup speed, which are its actual purposes. The opacity is a side effect, not a security feature, and it falls away as soon as a disassembler parses the format.
Two consequences follow. First, any string in your JavaScript, an API key, a URL, a secret, ends up as a string in the bytecode and is directly extractable, so Hermes hides secrets no better than a plaintext bundle once someone looks. Second, your logic is recoverable, so proprietary algorithms or client-side checks you assumed were hidden are not. Treating Hermes as a wall leads to designs that trust the client because the code seemed inaccessible, which is a mistake. The honest posture is that a Hermes app is reverse-engineerable, with a bit more effort than a text bundle, and no more secret for it.
Analyzing your own app's bundle
The defensive use of this is to examine your own app's HBC bundle and see exactly what an analyst would, on a machine you own. Extract the compiled bundle from your own app package, the HBC file inside your APK or IPA, and run a disassembler such as hbctool against it, then look through the output for readable strings and recognizable logic. Searching the extracted bytecode for secret patterns, API keys, and endpoints quickly shows what is exposed, because those strings survive compilation intact.
Keep the exercise to your own app. Only analyze applications you have the right to test, work on your own machine with your own build, and use the findings to fix what should not be there. This mirrors how OWASP frames resilience and code review: understanding what is recoverable from your build so you can remove what must not be exposed. Running a disassembler over your own Hermes bundle is a legitimate self-assessment, and it usually makes the point faster than any argument that Hermes is not protection.
What this means for your app
The practical meaning is that you must design as though your React Native code and its strings are visible, because with Hermes they effectively are. Do not place any secret, an API key, a token, a credential, in your JavaScript, because it will ship as an extractable string in the bytecode. Route anything that needs a privileged secret through a backend so the secret lives on your server and never in the bundle, and enforce trust on the server rather than in client-side logic that a disassembler can read and a runtime hook can alter.
This is the same conclusion that applies to any mobile client, and Hermes does not change it. What Hermes gives you is a modest increase in the effort required to read your code, which deters the most casual inspection but not a motivated one. So use it for its real benefits, performance and startup time, and pair it with the assumption that the code is transparent to anyone who wants to look. Anything whose exposure you cannot tolerate belongs on the server, not in the app.
Remediation
Remediation centers on removing what should not be recoverable and, optionally, raising the bar. First, get secrets out of the bundle entirely and behind a backend proxy, since that is the exposure that actually matters and Hermes does nothing to prevent it. Enforce authorization server-side so that reading or altering the client does not grant access, and consider server-side attestation for sensitive operations.
If you also want to slow down analysis of your logic, apply JavaScript obfuscation before Hermes compilation, which transforms the code so that even recovered logic is harder to follow, though it remains friction rather than a boundary and a determined analyst can still work through it. Keep dependencies current, since third-party code ships in the same bundle. The order of priority is clear: removing secrets and enforcing server-side trust are the real fixes, while obfuscation is an optional extra that raises cost without changing the fundamental reality that the client is reverse-engineerable.
Hermes protection at a glance
Comparing a plain bundle to Hermes bytecode clarifies what compilation does and does not change. The table below sets them side by side.
| Aspect | Plain JavaScript bundle | Hermes bytecode, HBC |
|---|---|---|
| Readability | Readable text | Binary, needs disassembly |
| Strings and secrets | Directly visible | Still extractable after disassembly |
| Program logic | Directly readable | Recoverable via a decompiler |
| Real obfuscation | No | No, only a higher bar |
Read the table across each row: Hermes raises the effort of the first column but does not change the outcome, so treat both as reverse-engineerable.
Hardening checklist
Working through these steps protects what Hermes does not. The checklist below covers them.
| Step | Action | Done? |
|---|---|---|
| Remove secrets from the bundle | No keys, tokens, or credentials in the JavaScript | [ ] |
| Use a backend proxy | Route privileged calls through your server | [ ] |
| Analyze your own HBC | Extract and disassemble your bundle to see what is exposed | [ ] |
| Enforce server-side trust | Do not trust client-side logic or checks | [ ] |
| Obfuscate if needed | JavaScript obfuscation before Hermes, as friction | [ ] |
| Scan the build | Catch leaked secrets before release | [ ] |
The step that matters most is removing secrets from the bundle, because that is the exposure Hermes does nothing to prevent and the one an attacker most wants.
Scan your build for exposed strings
Because Hermes preserves strings and a leaked secret is easy to miss in a compiled bundle, scanning what actually ships is the reliable way to know what is recoverable from your app.
A scanner like PTKD.com analyzes your build and reports issues such as leaked keys and secrets, insecure data storage, and over-broad permissions by severity, mapped to OWASP MASVS, so a secret sitting in your Hermes bundle is flagged before an attacker disassembles it out. To be clear about the boundary: PTKD does not obfuscate your bytecode or make Hermes a protection, which it is not, and it does not perform a live decompilation for you. It finds the secrets and issues in the shipped app so you know what to remove and move server-side.
What to take away
- Hermes compiles React Native JavaScript to HBC bytecode, which is harder to read than a plaintext bundle but is not obfuscation and not protection.
- HBC is a defined binary format, so tools like hbctool disassemble and reassemble it and decompilers recover pseudo-JavaScript, while strings including secrets stay extractable.
- Analyze your own app's HBC bundle on a machine you own to see exactly what an attacker would recover, and use it to remove what should not be there.
- Design as though your React Native code and strings are visible: keep no secrets in the bundle, route privileged calls through a backend, and enforce trust server-side.
- Obfuscation before Hermes adds friction but not a boundary, so prioritize removing secrets, and scan the build with a tool like PTKD.com.




