TL;DR: An APK is a ZIP archive, but its contents are compiled: Dalvik bytecode in
classes.dexand a binary manifest. JADX (v1.5.6, released July 10, 2026) converts that bytecode back into readable Java source. apktool (v3.0.3, released July 20, 2026) decodes resources and produces editable smali code, and can rebuild the APK. Use JADX to read code, apktool to modify it. Neither can turn native.solibraries back into Java. Stick to apps you own or that are open source.
Decompiling an Android app is a standard part of security research and learning how apps are built. The two open-source tools that cover almost every case are JADX, which turns Dalvik bytecode back into readable Java, and apktool, which decodes everything else and can rebuild the app. This guide covers what is inside an APK, installing both tools, a practical workflow for each, and the honest limits of decompilation.
A note on scope
Decompile apps you own, apps that are open source, or apps where you have permission. Reading your own app’s bytecode to understand a crash or auditing an open-source app’s behavior are legitimate research and learning uses. apktool’s own documentation states it is not intended for piracy. Analyzing code is one thing; republishing someone else’s code or stripping license checks is another.
What is actually inside an APK
An APK is a ZIP archive. As the apktool documentation puts it, APKs are “nothing more than a zip file containing resources and assembled java code” (apktool.org/docs/the-basics/intro). Renaming app.apk to app.zip and opening it shows the real layout:
| File or folder | What it is | Readable without tools? |
|---|---|---|
classes.dex |
Compiled Dalvik bytecode, all of the app’s Java/Kotlin code | No |
AndroidManifest.xml |
Permissions, components, app metadata, in binary XML form | No |
resources.arsc |
Compiled resource table (strings, IDs, configuration values) | No |
res/ |
Layouts, drawables, and values, some compiled | Partially |
assets/ |
Raw files shipped with the app | Yes |
lib/ |
Native .so libraries, one folder per CPU architecture |
No, machine code |
META-INF/ |
Signatures and signing certificates | Partially |
Unzipping gets you the files, but the interesting ones are compiled. That is where the two tools come in.
JADX vs apktool: which tool does what
These tools solve different halves of the problem. Picking the right one first saves an hour of confusion:
| JADX | apktool | |
|---|---|---|
| Code output | Readable Java source | Smali (Dalvik assembly) |
| Resources | Decoded, read-only | Decoded and editable |
| Rebuild an APK | No | Yes |
| Best for | Reading and understanding code | Modifying, translating, repackaging |
| Latest release | v1.5.6 (July 10, 2026) | v3.0.3 (July 20, 2026) |
| GitHub stars | 50,573 | 25,642 |
| Java required | Java 11 or later, 64-bit | Java 8 minimum |
JADX gives you Java you can read. apktool gives you smali, which is precise but verbose, plus decoded resources you can edit and an APK you can rebuild. Most analysis work starts with JADX; most modification work needs apktool.
Installing JADX
JADX needs a 64-bit Java 11 or later installed first. The official install paths from the project README:
- macOS:
brew install jadx - Arch Linux:
sudo pacman -S jadx - Linux (any distro):
flatpak install flathub com.github.skylot.jadx - Windows: download the ZIP from the releases page, unpack it, and run
jadx.bat(command line) orjadx-gui.bat(graphical) from thebinfolder
Verify with jadx --version. Building from source is unnecessary for normal use, but if you ever need it, it requires JDK 17 or higher.
Installing apktool
apktool needs a minimum of Java 8. The official install guide covers every OS:
- Linux / macOS: download the wrapper script and the latest
apktool.jar, rename the jar toapktool.jar, move both to/usr/local/bin, and make them executable withchmod +x - Windows: download
apktool.batand the latest jar, rename the jar toapktool.jar, and place both inC:\Windows(or any folder on your PATH) - macOS shortcut:
brew install apktool
The wrapper scripts exist so you can type apktool instead of java -jar apktool.jar every time.
Decompiling with JADX
Get an APK first. The cleanest source is your own app’s debug build (in app/build/outputs/apk/), or an open-source app’s APK from its releases page.
The graphical way
jadx-gui /path/to/app.apk
The GUI opens the package tree on the left. From there:
- Open
AndroidManifest.xmlunder resources to see permissions and components in readable form - Browse
sources/by package name to read the Java code - Use text search (
Ctrl+Shift+F) to find strings likeapi_key,http, orSharedPreferences - Right-click any method and choose Find usage to trace where it is called
- Export everything with File > Save all
The command-line way
jadx -d ./decoded /path/to/app.apk
This writes two folders into ./decoded: sources/ with the decompiled Java and resources/ with the decoded manifest and assets. Useful flags, verified against the current CLI source:
| Flag | What it does |
|---|---|
-r / --no-res |
Skip resource decoding, decompile code only |
-s / --no-src |
Skip decompilation, decode resources only |
-j / --threads-count |
Number of processing threads for large APKs |
--single-class |
Decompile one class by name instead of the whole app |
--show-bad-code |
Show code JADX could not decompile cleanly, marked as comments |
--deobf |
Rename obfuscated identifiers; names shorter than 3 characters get renamed by default |
JADX also accepts .dex, .jar, .aar, .aab, .xapk, and .apkm files directly, so split APK bundles do not need to be merged first.
Decoding with apktool
Where JADX produces readable Java, apktool produces an editable project:
apktool d app.apk
This creates an app/ folder containing the decoded AndroidManifest.xml, the res/ folder in source form, and a smali/ folder with the bytecode disassembled into smali files. Smali is Dalvik assembly: precise, but far more verbose than the Java that JADX reconstructs.
To rebuild after edits:
apktool b app
The rebuilt APK lands in app/dist/. It is unsigned, so it needs to be signed (for example with apksigner) before it can be installed. The rebuild round-trip is the reason apktool exists: decode resources to nearly original form, modify them, and build again.
When decompilation will not work
Decompilers have hard limits. Knowing them avoids wasted afternoons:
- Native code. Files under
lib/are compiled machine code, not bytecode. JADX shows only the Java-side JNI declarations. Reading the actual logic needs a native disassembler such as Ghidra, a different skill set entirely. - Unity and IL2CPP games. The game logic lives in
libil2cpp.soplus aglobal-metadata.datfile. JADX decompiles the Unity wrapper and nothing of the game itself. - Heavy obfuscation. Tools like DexGuard add string encryption and control-flow obfuscation. JADX’s
--deobfrenames short identifiers, but it cannot recover encrypted strings or undo deliberately mangled control flow. - Packers. Some APKs ship a small stub that unpacks the real DEX at runtime. Static tools only see the stub; the real code never sits on disk in analyzable form.
- Kotlin output is noisy. Kotlin compiles to bytecode with synthetic methods and metadata. JADX decompiles it, but coroutines and lambdas come out harder to read than plain Java.
A quick rule of thumb: if the app’s core logic is in Java or Kotlin bytecode, JADX reads it well. If the logic was moved into native code or deliberately hidden, no decompiler gets it back for free.
Key takeaways
- An APK is a ZIP of compiled parts; unzipping alone does not make them readable.
- JADX (v1.5.6) reconstructs Java source for reading. apktool (v3.0.3) decodes resources and smali for editing and rebuilding.
- Both install in minutes:
brew install jadxon macOS, wrapper script plus jar for apktool, Java 11+ for JADX and Java 8+ for apktool. jadx -d ./decoded app.apkandapktool d app.apkare the two commands that start nearly every workflow.- Native libraries, IL2CPP games, packers, and heavy obfuscation are beyond what either tool can reverse.
- Decompile your own apps or open-source ones; the tools’ authors draw the line at piracy, and so should you.
References
- skylot/jadx — README: install methods, Java 11+ requirement, supported input formats
- JADX releases — v1.5.6 published July 10, 2026
- iBotPeaches/Apktool — README: purpose, rebuild workflow, not intended for piracy
- apktool releases — v3.0.3 published July 20, 2026
- apktool install guide — wrapper scripts, Java 8 minimum,
brew install apktool - apktool introduction — APK contents,
apktool dwalkthrough
Was this useful?
Thanks for the feedback.
5 comments