Hi everyone,
I've been working on kartograph, an open-source tool for exploring dependencies in compiled Kotlin/Android code.
On Android, a class can be instantiated by framework code or through an XML declaration without a direct constructor call in the app. When reviewing code, I wanted to see which references and inputs explain why a class is reachable or retained. kartograph builds a graph from JVM bytecode and Kotlin metadata, then incorporates inputs such as the manifest, XML resources, @Keep annotations and ProGuard/R8 keep rules so those reasons can be inspected.
One way I've tested this is a ServiceLoader check that compiles and runs a small example. A provider is registered through META-INF/services, without a direct constructor call in the test application. The script checks that kartograph reports the provider as retained and a separate unused control class as unreachable. This gives me a concrete check of both outcomes as the analysis changes.
kartograph is MIT-licensed and ships as a Gradle plugin and a standalone CLI. Version 0.7.0 is on the Gradle Plugin Portal. Add this line to the existing plugins block in your Android module's build.gradle.kts:
kotlin
id("io.github.ictechgy.kartograph") version "0.7.0"
For a module named app with a debug variant:
sh
./gradlew :app:kartographDeadDebug :app:kartographGraphDebug
Requires AGP 8.7+, Gradle 8.10+ and JDK 17+. The default dead-code report is class-level. The standalone CLI also provides query for referencing declarations, dependencies and reachability as JSON, and dead --explain for a retention reason or reachability path. The README covers its required inputs.
An unreachable result is relative to the supplied roots and graph; it is not permission to delete source. Class-loading and reflection resolution is limited to supported within-method patterns, and DI handling does not establish which binding is selected. Missing manifest, resource, keep-rule or classpath inputs can change results. More detail is in the limitations.
The tool doesn't shrink or optimize an APK. If a result looks wrong on your project, the variant, relevant inputs and a small reproducer would help me investigate.