# Shrinking a Kotlin binary by 99.2%

DevFeed: [Shrinking a Kotlin binary by 99.2%](<https://devfeed.tech/articles/shrinking-a-kotlin-binary-by-99-2-20969.md>)

Original publisher: [Read original article](<https://jakewharton.com/shrinking-a-kotlin-binary/>)

Published: 2020-08-24T00:00:00Z

Content type: article

Language: en

Sources: [Jake Wharton](<https://devfeed.tech/sources/jake-wharton.md>)

Topics: [Kotlin](<https://devfeed.tech/topics/kotlin.md>), [Gradle](<https://devfeed.tech/topics/gradle.md>), [ci](<https://devfeed.tech/topics/ci.md>), [Compiler](<https://devfeed.tech/topics/compiler.md>), [pull-requests](<https://devfeed.tech/topics/pull-requests.md>)

Tags: [ci](<https://devfeed.tech/tags/ci.md>), [compiler](<https://devfeed.tech/tags/compiler.md>), [dependencies](<https://devfeed.tech/tags/dependencies.md>), [gradle](<https://devfeed.tech/tags/gradle.md>), [kotlin](<https://devfeed.tech/tags/kotlin.md>), [pull-requests](<https://devfeed.tech/tags/pull-requests.md>)

## AI overview

The article explains how to shrink a Kotlin binary used to inspect dependency-tree changes. It moves from a Kotlin script to a classic Kotlin Gradle project, produces a self-executing fat binary, and identifies unnecessary compiler, reflection, and Java 9 module-system files for removal.

## Source excerpt

We'll get to the shrinking, but first let's motivate the binary in question. Three years ago I wrote the "Surfacing Hidden Change to Pull Requests" post which covered pushing important stats and diffs into PRs as a comment. This avoids surprises with changes that affect binary size, manifests, and dependency trees. Showing dependency trees used Gradle's dependencies task and diff -U 0 to display changes from the previous commit. The example in that post bumped the Kotlin version from 1.1-M03 to 1.1-M04 producing the following diff: @@ -125,2 +125,3 @@ -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.0.4 -> 1.1-M03 -| \--- org.jetbrains.kotlin:kotlin-runtime:1.1-M03 +| \--- org.jetbrains.kotlin:kotlin-stdlib:1.0.4 -> 1.1-M04 +| \--- org.jetbrains.kotlin:kotlin-runtime:1.1-M04 +| \--- org.jetbrains:annotations:13.0 @@ -145,2 +146 @@ -+--- org.jetbrains.kotlin:kotlin-stdlib:1.1-M03 -+--- org.jetbrains.kotlin:kotlin-runtime:1.1-M03 ++--- org.jetbrains.kotlin:kotlin-stdlib:1.1-M04 Aside from seeing the version bump reflected, there's two extra facts here we can deduce about the change: The kotlin-runtime dependency gained a dependency on Jetbrains' annotations artifact as seen in the first section of the diff. A direct dependency on kotlin-runtime was removed as seen in the second section of the diff. This is fine, as the first section already tells us that kotlin-runtime is a dependency of kotlin-stdlib. These two facts are shown in the displayed diff, but there's a subtle third fact which is only implied. Because the first section is indented, we know that one of our direct dependencies has a transitive dependency on kotlin-stdlib. Unfortunately we have no idea which dependency is affected. To solve this problem I wrote a tool called dependency-tree-diff which shows the path to a root dependency for any changes in the tree. +--- com.jakewharton.rxbinding:rxbinding-kotlin:1.0.0 -| \--- org.jetbrains.kotlin:kotlin-stdlib:1.0.4 -> 1.1-M03 -| \--- org.jetbrains.kotlin:kotlin-r