Gradle & Code Quality

Read a Gradle Dependency Tree and Find the Selected Version

A Gradle dependency tree shows requested modules, selected versions and the paths that introduced them. Read the tree for a specific configuration; a project-wide list without variant context can answer the wrong question.

By , FounderUpdated 3 min read

Generate a focused report

BASH · REFERENCE EXAMPLE
./gradlew :app:dependencies --configuration releaseRuntimeClasspath
./gradlew :app:dependencyInsight \
  --dependency example-library \
  --configuration releaseRuntimeClasspath

Replace example-library with the relevant module selector. Use the correct module and flavor-specific configuration if your project does not expose the simple release name.

Read version selection correctly

In the Gradle report format, an arrow from one version to another indicates selection or substitution, not two copies of the same dependency being packaged automatically. Repeated subtrees can be abbreviated in the output.

Do not add every visible requested version together to estimate the application's dependency count. The resolved result and variant selection determine what is actually used.

Ask why, not only what

Question Report to use
What is in the release runtime graph? dependencies for that configuration
Why was this version selected? dependencyInsight
Which parent introduced it? Incoming paths in the insight report
Does debug differ from release? Compare corresponding configurations

Platforms, constraints, conflict resolution and substitutions can all influence the selected result. A version catalog alias alone does not guarantee a particular resolved version.

Preserve a reproducible snapshot

Save the report with the commit, wrapper version and relevant lockfiles. Avoid making a conclusion from a developer machine using uncommitted build changes or different repository credentials.

If a dependency is missing, check whether it belongs to another configuration, feature module or included build before concluding that it is not shipped anywhere.

Connect the graph to the artifact

APKLint's Gradle tools can review declarations, and its APK tools can inspect package contents. Neither replaces the build's resolved graph. Use the graph to identify expected code and the artifact to confirm what reached the release, especially when libraries package native code or bundle other classes internally.

Read a small hypothetical resolution result

releaseRuntimeClasspath
+--- example:reader:2.0
|    \--- example:codec:1.0 -> 1.4
\--- example:writer:3.0
     \--- example:codec:1.4

This invented graph contains two incoming paths to the codec module and one selected codec version. It does not describe two packaged copies of codec. The next investigation is whether both reader and writer are compatible with the selected API. Record the selected coordinate once, then retain the incoming paths as the explanation of why it is present. The names and versions here are teaching examples, not coordinates to add to an application.

Use an insight report for the codec selector to distinguish ordinary conflict selection from a platform constraint or an explicit rule. Gradle's dependency report reference explains the notation and selection reasons. Avoid interpreting a single arrow as a vulnerability warning: it describes resolution, while security assessment requires separate evidence about the selected component.

Compare meaningful fields between releases

When comparing two commits, keep the module, configuration and task invocation identical. Record additions, removals and selected-version changes, then investigate why each changed. Also note altered incoming paths even when a selected version stays the same. Removing reader in the example would not remove codec while writer still requires it, so a declaration diff alone would overstate the effect.

Keep configuration headers with exported text. A file containing only a subtree can be mistaken for a complete release graph and hides whether the report came from a test or runtime configuration. If a report marks resolution as failed, do not treat the partial tree as a complete inventory. Resolve the failure or label that part of the result incomplete.

For packaging questions, connect the selected component with the actual artifact contents. Resource shrinking, code shrinking and feature delivery can make the installed result differ from a simple count of graph entries. The dependency report explains build inputs; it is not an installed-size measurement. Pairing it with an APK inspection avoids assigning the entire binary size of a library to every path that mentions that library.

Sources and further reading

  1. Gradle: Viewing and debugging dependencies

Reference review: 29 September 2026. Examples illustrate the workflow; check your installed versions, release artifact and account-specific Console requirements before applying them. This guide is not a claim that APKLint executed your project or verified your private account.

APKLint

Android inspection tools and practical release guides. About APKLint · Report a correction