Byte-identical classes
1.5%
Metrics · regenerated nightly
Every number comes from automated runs; nothing is picked by hand. A source that could not be read says so instead of showing a number.
1.5%
15.1%
80.3%
100.0%
Headline metric
krusty aims to emit .class files byte for byte identical to kotlinc's. An identical class needs no tests to trust: it is exactly what kotlinc would have shipped, which matters most for code with few or no tests. A class counts only when the whole file matches.
Each project is built from a pinned commit with its own Gradle build, once with kotlinc and once with the krusty Gradle plugin. A compilation is one Kotlin/JVM compile task of the reference build, main and test source sets alike. krusty built it when it compiled it itself. When it did not, every class of that compilation counts as different, and the reason is one of: left to kotlinc (the build uses a compiler plugin or argument krusty does not implement yet, so the plugin hands the task to kotlinc), failed (krusty reported an error), or not run (a task it depends on failed first). The run's summary artifact lists every reason (run of 2026-11-09).
| Project | Identical classes | Built | Not built | Patch |
|---|---|---|---|---|
| koin 33,677 Kotlin lines | 2.6% 97 / 3,705 | 5 / 19 | 5 failed9 not run | |
| leakcanary 100,627 Kotlin lines | 1.3% 25 / 1,798 | 6 / 34 | 2 left to kotlinc2 failed24 not run | |
| Maestro 65,644 Kotlin lines | 1.2% 27 / 2,156 | 1 / 19 | 4 failed14 not run | Maestro.patch |
| mirai 156,078 Kotlin lines | 0.0% 9 / 11,399 | 3 / 56 | 5 failed48 not run | mirai.patch |
| moshi 16,749 Kotlin lines | 10.1% 52 / 512 | 5 / 12 | 2 failed5 not run | moshi.patch |
| nowinandroid 26,596 Kotlin lines | 14.4% 160 / 1,110 | 17 / 58 | 30 left to kotlinc2 failed9 not run | |
| okhttp 126,665 Kotlin lines | 0.0% 0 / 1,483 | 0 / 38 | 4 left to kotlinc1 failed33 not run | okhttp.patch |
| okio 46,812 Kotlin lines kotlinc build failed (exit 1) · logs | 0.0% 0 / 343 | 0 / 6 | 2 left to kotlinc3 failed1 not run | okio.patch |
| quarkdown 87,771 Kotlin lines | 2.9% 69 / 2,345 | 6 / 37 | 2 failed29 not run | |
| Unciv 139,231 Kotlin lines | 0.0% 0 / 3,341 | 0 / 4 | 4 left to kotlinc | |
| ktor | no result: the project's job failed before it compared anything · logs | |||
| kotlinx.coroutines | no result: the project's job failed before it compared anything · logs | |||
| Exposed | no result: the project's job failed before it compared anything · logs | |||
| Total | 1.5% 439 / 28,192 | 43 / 283 | ||
Totals include every project with a result, also one whose own kotlinc build failed: its compilations count as far as the kotlinc build produced classes. Every project is built with the newest Kotlin release krusty supports; a linked patch is what the corpus changes to make that build work, applied to both builds.
Over time
One point per corpus run that measured all 13 listed projects, each measure on its own scale. Partial runs are in the table below.
| Date | krusty | Projects | Identical classes | Built |
|---|---|---|---|---|
| 2026-11-09 | 4c1f08c | 10 | 1.5% 439 / 28,192 | 43 / 283 |
| 2026-11-07 | 70a8549 | 13 | 0.8% 494 / 61,192 | 56 / 580 |
Time and memory
The same two builds of each project, each alone on its own runner after a warm-up build, both offline from the same caches. Each cell shows krusty's build against kotlinc's: −40% means 40% less. Whole builds are compared only where both did the same work: both Gradle builds succeeded and krusty compiled something with no compilation failed or skipped. Elsewhere one build stopped early or ran different tasks, so its numbers are shown but marked not comparable; results recorded before the corpus kept the build outcomes are marked comparability unknown. Whole-build wall time barely moves yet, because krusty builds only 15.1% of the compilations: kotlinc still compiles the rest in the krusty build, and Gradle's own work is the same in both. Compile time of what krusty built compares only the compilations krusty compiled itself. Compiler RSS is the Kotlin daemon's peak in the kotlinc build and krusty's in the other; where krusty built little, the Kotlin daemon still runs in the krusty build, so build RSS is the fairer memory figure.
| Project | Build wall time | Build peak RSS | Compile time, what krusty built | Compiler peak RSS |
|---|---|---|---|---|
| koin | not comparable 44.3 s → 42.3 s | not comparable 2,854 MB → 2,272 MB | −83% 19.6 s → 3.4 s | not comparable 1,554 MB → 412 MB |
| leakcanary | not comparable 114.8 s → 50.3 s | not comparable 3,888 MB → 2,662 MB | −89% 31.7 s → 3.6 s | not comparable 2,014 MB → 329 MB |
| Maestro | not comparable 88.0 s → 38.1 s | not comparable 3,340 MB → 1,508 MB | −95% 8.8 s → 0.4 s | not comparable 1,918 MB → 158 MB |
| mirai | not comparable 116.8 s → 43.6 s | not comparable 5,928 MB → 2,763 MB | −89% 17.9 s → 2.0 s | not comparable 4,427 MB → 295 MB |
| moshi | not comparable 70.1 s → 43.4 s | not comparable 2,566 MB → 1,714 MB | −84% 26.0 s → 4.1 s | not comparable 1,313 MB → 158 MB |
| nowinandroid | not comparable 137.9 s → 134.8 s | not comparable 7,985 MB → 6,768 MB | −74% 80.2 s → 21.1 s | not comparable 3,690 MB → 159 MB |
| okhttp | not comparable 135.3 s → 65.3 s | not comparable 5,709 MB → 3,249 MB | nothing built | not comparable 3,267 MB → 134 MB |
| okio | not comparable 80.6 s → 54.5 s | not comparable 4,215 MB → 3,526 MB | nothing built | not comparable 2,388 MB → 120 MB |
| quarkdown | not comparable 102.5 s → 57.0 s | not comparable 3,272 MB → 2,224 MB | −88% 33.8 s → 4.1 s | not comparable 1,672 MB → 260 MB |
| Unciv | not comparable 136.8 s → 157.7 s | not comparable 4,300 MB → 5,026 MB | nothing built | not comparable 3,476 MB → 0 MB |
Kotlin's own test suite
Every applicable case of JetBrains' codegen/box tests, compiled by krusty and by the matching kotlinc. Conformance is the share of cases whose box() returns "OK". The byte-equality gauge is a progress measure, not a share of identical classes: each class counts its bytes before the first difference from kotlinc's, over the longer of the two files, and a failing case counts zero; 100% means every class is identical. See docs/TEST_HARNESS.md.
| Kotlin | JVM byte-equality gauge | JVM conformance | Native conformance |
|---|---|---|---|
| 2.4.21 | 80.3% 38,235,399 of 47,611,346 bytes | 100.0% 7,372 of 7,372 cases | 63.7% 4,668 of 7,318 cases |
| 2.4.20 | 80.3% 38,232,345 of 47,608,287 bytes | 100.0% 7,371 of 7,371 cases | 63.7% 4,668 of 7,317 cases |
| 2.4.10 | 79.8% 37,058,930 of 46,433,318 bytes | 100.0% 7,254 of 7,254 cases | 63.8% 4,606 of 7,209 cases |
| 2.4.0 | 79.8% 37,050,732 of 46,424,214 bytes | 100.0% 7,253 of 7,253 cases | 63.8% 4,605 of 7,208 cases |
krusty itself
The share of krusty's own source its test suite exercises, as the floor the coverage gate enforces on every change (coverage-baseline.json). The measured coverage of a change is at least this.
| Measure | Covered | Of | Share |
|---|---|---|---|
| Lines | 279,302 | 334,337 | 83.5% |
| Functions | 23,275 | 27,939 | 83.3% |
| Regions | 422,354 | 522,715 | 80.8% |
| Branches | 37,096 | 54,704 | 67.8% |
Not measured yet
The pages workflow rebuilds this page every night, after each nightly corpus run and after every release, from the latest successful master CI run, the summary artifacts of the nightly corpus runs and the coverage baseline. A malformed report stops the deploy rather than publish a wrong number.