Tutorials

How to Decompile an APK to Java Source with JADX (and When It Won’t Work)

Springmusk Springmusk 7 min read 5 comments
Abstract illustration showing dense binary code blocks dissolving into readable lines of source code

TL;DR: An APK is a ZIP archive, but its contents are compiled: Dalvik bytecode in classes.dex and 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 .so libraries 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) or jadx-gui.bat (graphical) from the bin folder

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 to apktool.jar, move both to /usr/local/bin, and make them executable with chmod +x
  • Windows: download apktool.bat and the latest jar, rename the jar to apktool.jar, and place both in C:\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.xml under 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 like api_key, http, or SharedPreferences
  • 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.so plus a global-metadata.dat file. 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 --deobf renames 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 jadx on macOS, wrapper script plus jar for apktool, Java 11+ for JADX and Java 8+ for apktool.
  • jadx -d ./decoded app.apk and apktool d app.apk are 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

5 comments

Join the discussion

Your email address will not be published. Required fields are marked *