Skip to main content

pyjadx

Python bindings for JADX via JPype. Decompile Android APK and DEX files to Java source from Python.

from pyjadx import Jadx

with Jadx("app.apk") as jadx:
    for cls in jadx.classes:
        print(cls.full_name)
        print(cls.code)

Why pyjadx?

JADX is the leading open-source Android decompiler — it produces clean Java/Kotlin source from Dalvik bytecode, preserving class hierarchies, generics, exception handling, and annotations. pyjadx brings this into Python without subprocess overhead: JADX runs in-process via JPype.

Install

pip install pyjadx

Requirements: JDK 11+ (JADX JARs are downloaded automatically on first use).

Quick start

from pyjadx import Jadx

with Jadx("app.apk") as jadx:
    # All top-level classes (inner classes via cls.inner_classes)
    for cls in jadx.classes:
        print(cls.full_name, len(cls.methods), "methods")

    # Search by fully qualified name
    main = jadx.search_class("com.example.MainActivity")
    if main:
        print(main.code)

    # Method-level decompilation
    for method in main.methods:
        print(f"{method.name}: {method.code}")

    # Cross-references
    for method in main.methods:
        print(f"{method.name} called by: {[c.name for c in method.callers]}")

    # Package navigation
    for pkg in jadx.packages:
        print(pkg.name, len(pkg.classes), "classes")

Supported inputs

Format Example
APK Jadx("app.apk")
DEX Jadx("classes.dex")
Multi-DEX APK Handled transparently — all classes merged

API reference

Jadx(path, *, threads=None, mode="auto", code_cache=False)

Main entry point. Use as a context manager or call load()/close() manually.

Parameter Description
path Path to APK or DEX file
threads JADX thread pool size (None = CPU count)
mode "auto", "restructure", "simple", or "fallback"
code_cache False = in-memory cache (default), True = disk-backed

Properties:

Property Type Description
classes list[JavaClass] Top-level classes across all DEX files
packages list[JavaPackage] Package-level navigation
class_count int Number of top-level classes
java JObject Escape hatch to underlying jadx.api.JadxDecompiler

Methods:

Method Description
load() Load and resolve classes (called by __enter__)
close() Release resources (called by __exit__)
decompile_all() Eagerly decompile all classes
search_class(name) Find class by fully qualified name

JavaClass

Property Type Description
name str Short name ("MainActivity")
full_name str Fully qualified ("com.example.MainActivity")
package str Package name
code str Decompiled Java source (lazy, cached)
smali str Smali disassembly (lazy, cached)
methods list[JavaMethod] Methods in this class
fields list[JavaField] Fields in this class
inner_classes list[JavaClass] Inner/anonymous classes
declaring_class JavaClass | None Parent class (if inner)
top_class JavaClass Outermost enclosing class
dependencies list[JavaClass] Classes this class depends on
is_inner bool Whether this is an inner class
java JObject Escape hatch to jadx.api.JavaClass

JavaMethod

Property Type Description
name str Method name
full_name str Fully qualified with class
code str Decompiled source (lazy, cached)
callers list[JavaMethod] Methods that call this one (lazy, cached)
callees list[JavaMethod] Methods this one calls (lazy, cached)
override_related list[JavaMethod] Bidirectional override chain
declaring_class JavaClass Class this method belongs to
java JObject Escape hatch to jadx.api.JavaMethod

JavaField

Property Type Description
name str Field name
full_name str Fully qualified with class
type str Field type as string
callers list[JavaMethod] Methods referencing this field (lazy, cached)
declaring_class JavaClass Class this field belongs to
java JObject Escape hatch to jadx.api.JavaField

JavaPackage

Property Type Description
name str Full package name
classes list[JavaClass] Classes in this package
sub_packages list[JavaPackage] Sub-packages
java JObject Escape hatch to jadx.api.JavaPackage

Escape hatch

Every wrapper exposes its underlying JADX Java object via .java. This lets you call any JADX API we haven't wrapped yet:

with Jadx("app.apk") as jadx:
    cls = jadx.search_class("com.example.Foo")
    # Call JADX Java API directly
    code_info = cls.java.getCodeInfo()

JVM coexistence

pyjadx coexists with other JPype consumers (e.g., PyGhidra) in the same process. If a JVM is already running, pyjadx.start() adds JADX JARs to the existing classpath. If not, it starts one.

import pyghidra
pyghidra.start()  # starts JVM for Ghidra

import pyjadx
pyjadx.start()    # adds JADX JARs to existing JVM — no conflict

Configuration

Custom JADX installation:

# Via environment variable
# export JADX_HOME=/opt/jadx

# Or at runtime
import pyjadx
pyjadx.start(jadx_home="/opt/jadx")

JAR caching: JADX JARs are auto-downloaded from Maven Central on first use and cached at ~/.pyjadx/jars/<version>/.

License

MIT

Metadata

Release files for pyjadx 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pyjadx 0.1.1
File Size Uploaded Provenance Actions
pyjadx-0.1.1.tar.gz 17.9 kB Without provenance Details for pyjadx-0.1.1.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for pyjadx 0.1.1
File Interpreter ABI Platform Actions
pyjadx-0.1.1-py3-none-any.whl Python 3 none any Details for pyjadx-0.1.1-py3-none-any.whl

Total release size: 28.4 kB

Release files / pyjadx-0.1.1.tar.gz

Download URL pyjadx-0.1.1.tar.gz
Size 17.9 kB
Tags Source
SHA-256 checksum
How to use checksums
e4ac12eb620805c4cb005b015aef2a33fd77f3024648169455d08d852ddaea83
BLAKE2b-256 checksum
How to use checksums
f6a23dc8fb4d2baba247a5e9934f3fc9306b387471fdce185ea4b2a6fa41dcdc
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Release files / pyjadx-0.1.1-py3-none-any.whl

Download URL pyjadx-0.1.1-py3-none-any.whl
Size 10.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
3fcf906e0455d7e059e37423101846badf24188a4f1de5b19c8ea773257a647f
BLAKE2b-256 checksum
How to use checksums
4838e98c20d5c2bd964f2d4437bbf1dd148c30d49baf1c40dd75f97836b9e46b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.10.12 {"installer":{"name":"uv","version":"0.10.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

Security for pyjadx 0.1.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.1 This release

2 release files No provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page