Kotlin kontra Java – Part 1 – Ecosystem

Richard Gross

When you start a new project on the JVM, should you pick Java or Kotlin?

Kotlin is used by Amazon, Atlassian, Duolingo, Google, JetBrains, Meta, Netflix, Uber and many more. Java is used by, well, „more than 3 billion devices“. Which one provides the biggest benefit, which one can give us an edge, which one should we pick?

After 20 years of building systems in Java and 8 years of doing the same in Kotlin, I’ve seen Kotlin earn its reputation as a natural evolution of Java. Rightfully so. Much of what we need can be expressed very cleanly with little verbosity.

But a language is not just its syntax. It’s not just how well we can model business problems in the language, or how terse the written code is, or if we have to write semicolons. It’s also about the tooling around it, who we can ask for help, and the libraries we can use. In short, a programming language is also about the ecosystem and tooling.

This article will compare the ecosystem of Java and Kotlin. In part two we will look into the multi-platform capabilities that both languages provide. In part three, we will dive deep into their modelling capabilities and give a verdict on which language to pick in 2026.

Ecosystem Evaluation Criteria

Programming languages ideally have:

  1. Expected longevity through pace and strong backward compatibility
  2. Developer availability and developer interest
  3. Quality IDE support
  4. Good Compile and Execution Performance
  5. Mature libraries and frameworks

Let’s break down each point.

Expected Longevity

One important way for programming languages to achieve longevity is by keeping pace with how we model software — e.g. adding new syntax/libraries/tools to make common cases simple to express — and at the same time ensuring backwards compatibility to how we used to model software. This is not about a fast release cadence but about a release cadence that is fast enough.

Java

It is safe to say that Java — developed by Oracle — has longevity. Version 1 was released in 1996. This year will see the release of version 26 and 27. Major versions are released every six months. These releases are deliberately conservative in how much is changed however. New features go through multiple rounds of previews (or incubation) before being finalized. A lot of important features have been added over the years. This language is not going away any time soon.

Additionally, the maintainers have taken great strides to ensure backwards-compatibility with little to no breaking changes. As an example, even libraries that use internal JDK functions, that were never meant for the public, can still be used. The maintainers have just changed the default and we have to opt-in to that behavior via flags like --add-opens. When features are removed (e.g. CORBA, Nashorn JavaScript Engine, see A visual chronicle of the JDK’s journey), it is only done when viable alternatives have been well-established. We can safely upgrade on our own schedule without having to rush to adapt to every new version.

A lot of companies do so and follow a slow upgrade path. New Relics State of Java Ecosystem 2024 suggests that 28,8% still use JDK 8 (released 2014), 32,9% use JDK 11 (2018) and only 35,4% use Java 17 (2021).

Kotlin

By comparison, Kotlin — developed by JetBrains — is only 10 years old. Version 1 was released in 2016 and version 2.3 and 2.4 will come this year. Major versions are released every six months, similar to Java, and tooling releases three months after the major release. Many of the features Kotlin already has are things that Java is working towards, albeit in different form. In recent years Kotlin has started to be a bit more conservative with features however and stabilizes only after multiple previews (experimental → alpha → beta). Google has given Kotlin strong support by making it the default programming language for Android in 2019. Google, JetBrains, Meta, Gradle, Uber, Kotzilla and Block are also members of the Kotlin Foundation, which “protects, promotes and advances the development of the Kotlin programming language.” This language is also not going away any time soon.

Kotlin is a bit different than Java though. It can compile to Java bytecode (all targets between Java 8 and 25 are supported) but does not bring a virtual machine that can execute said bytecode (if you discount multi-platform). This has consequences on their release process. They essentially treat their language like a compiler and only the newest version gets bugfixes. If users want new language features, new standard library functions or target newer JDKs, they have to update.

JetBrains has declared in their Kotlin evolution principles that they intend to make updates comfortable. They will announce removals (breaking changes) well in advance, mark things as deprecated and provide automated migration tools. Personally, I have seldom experienced breaking changes, and when they occur they are announced with a deprecation warning and an automated migration path. Kotlin has a @Deprecated(replaceWith="...") annotation that makes migrations of standard library methods painless. When a library method needs to be replaced, the replaceMe parameter tells my JetBrains IDE what to replace it with. Very comfortable.

Kotlin replaceWith inside @Deprecated provides automatic migration for one occurence or all

Verdict

In summary, both languages have similar longevity expectations. Java has stronger backward-compatibility guarantees, which is important given it is much older and has a wider install base. Kotlin, however, benefits from good IDE-integration that makes migrations almost painless.

Developer Availability and Interest

Does the programming language have enough developers, do they have significant experience and is there enough interest that new developers will show up? To answer these questions, we consider three widely cited surveys that together cover activity, interest, and actual usage:

The rankings show Java in the Top8, Kotlin in the top 15. Rust, released 2015, is included so we have another relatively recent language to use as a benchmark for how “new” ecosystems can still attract talent.

RankingGitHub PR + SO ActivityIEEE Spectrum InterestStackOverflow Extensive Work
1JavaScriptPython (1.0)JavaScript (69%)
2PythonJava (0,50)
3Java
8Java (30%)
13Kotlin (0,13)
14KotlinRust (0,13)Rust (15%)
15Kotlin (12%)
19Rust

If we look at JetBrains Developer Ecosystem Data Playground we see these rankings reflected in the data. There are about 20,8 million people that do some form of coding or programming. About 7,1 million people say Java is their primary language and about 2 million say Kotlin is theirs.

Verdict

The results are encouraging. We can pick either language and find developers who use it, have interest and have done extensive work. In my experience the syntax of Kotlin is so familiar to Java (and JavaScript) developers that onboarding them into a new project is a quick process measured in weeks not months.

Quality IDE Support

Java

Java has very good IDE support. It’s supported by IntelliJ, Eclipse and NetBeans out of the Box. Alternate editors (like Visual Studio Code or Vim/NeoVim) can get language support via a language server. One is maintained by the Eclipse Foundation, Red Hat and Microsoft. Another is maintained by Apache Netbeans. Red Hat also provides a VS Code plugin while the community provides a NeoVim Extension.

Kotlin

Kotlin is developed by JetBrains which make the excellent IntelliJ IDE (also the foundation for the free Android Studio). According to JRebel 2025 Java Developer Productivity Report 84% of Java developers use it, followed by 31% VS Code and 28% Eclipse (selecting multiple IDEs was allowed). Support in their own IDE is excellent and on-par or better than for Java.

But what about alternative IDEs? For one, JetBrains maintains an Eclipse plugin. For another they are now providing an official language server (albeit in pre-alpha), a VS Code plugin (not yet published to the Marketplace) and a VS Code Java to Kotlin converter. An community language server exists but that has been marked as deprecated in favour of the official one.

Verdict

Overall, Java users can choose from several mature, feature‑rich development environments across platforms. Kotlin support is strongest in IntelliJ‑based IDEs and Eclipse, while support in other editors currently relies on an official language server that is still in pre‑alpha and lacks some features.

Compile Performance

To get fast feedback, we need fast compilation. Without a compiled program (i.e. bytecode) we cannot launch our tests or start the application.

Benchmarking is Tricky

According to ad-hoc benchmarks by the mill build tool javac (the Java compiler) can compile 100k lines per second of Java code.

However, once a build tool like Gradle or Maven is involved that number goes down to 9000 respectively 6000 lines per second. One reason for that is that the javac is not kept “hot”, it is always cold-started which adds the regular Java startup overhead. Java programs are notorious for needing some time to reach peak performance and the compiler is no different. The other reason is that build tools do a lot more than the compiler including dependency management, module resolution, task/phase resolution, caching and invalidation.

Benchmark Setup

Comparing only the performance of the compiler is tricky, given that most projects use dependencies, are split into modules and have special task requirements. Within the scope of this article I will focus on comparing the speed of Gradle execution, normalized by the lines of code.

The sample Java project is Mockito (contains 63 984 Java RLoC). Mockito also contains about 2299 Kotlin RLoC, but they are deemed insignificant for this comparison and ignored. The sample Kotlin project is Exposed (97 204 Kotlin RLoC). Both are Gradle projects.

Tokei is used to count real lines of code (RLoC), i.e. pure code lines. Comments and empty lines are excluded as they do not concern the compiler. The number of Gradle projects is retrieved by executing ./gradlew projects. The dependencies of project are retrieved via ./gradle :*:dependencies. The Gradle version and deamon JVM are determined via ./gradlew --version.

./gradlew classes testClasses is executed once to download all dependencies. Afterwards the network is disabled and the following command is executed five times for both projects on the same machine:

./gradlew clean; time ./gradlew classes testClasses --no-build-cache

The median of these five runs is then normalized by the real lines of code. After the build is successful the number of executed tasks is recorded.

Verdict

Mockito (Java) is compiled with a median of 4 294 lines/s and Exposed (Kotlin) with a median of 5 849 lines/s. This makes Kotlin appear about 36% faster than Java for these two specific projects. I do not think this can be generalized as “Kotlin can compile faster than Java”. Kotlin is a more complex language and there are lots of things the compiler has to do to fit inside the JVM bytecode. The Java compiler has also been refined for much longer, so I find it doubtful that the Kotlin compiler is that much faster. It’s also noteworthy that both median compilation times are slower than what was benchmarked by the mill maintainers, but that can be attributed to different hardware setups. It would be interesting to do a deep-dive with many more projects, perhaps even bypassing Gradle completely and just using javac and kotlinc directly.

Nevertheless it seems like the Kotlin compiler rewrite that was delivered with Kotlin 2.0 was a success. JetBrains announced it would bring up to up to 94% compilation speed gains compared to 1.9.

In summary I would say that both Java and Kotlin provide comparable compilation speed, but our build tools still have room to grow.

Execution Performance

Bound to the same JVM

Since both Java and Kotlin run on the same JVM, their runtime performance is also tied to said machine. Which is good and bad.

Bad because the same startup (time to first useful piece of work), warmup (time to reach peak performance), scalability (throughput per resource) and memory consumption will affect both languages at execution time.

Good because the improvements that the JVM is doing in regards to startup (e.g. CRaC), warmup (e.g. AOT caching), scalability (e.g. Z Garbage Collector, Shenandoah, Virtual Threads, Integrity by Default) and memory consumption (e.g. Valhalla) will benefit both languages.

Kotlin can of course improve on that with their compiler but only up to the limits of the bytecode. For example Kotlin added Coroutines (Kotlin 1.3, Oct 2018), that increase the throughput of I/O-bound applications, long before Java added Virtual Threads (JDK 21, Sep 2023). But these could not circumvent thread pinning (synchronized methods that hold onto a thread doing I/O) until the JDK solved it (JDK 24, Mar 2025). Kotlin also provides value classes (Kotlin 1.5, May 2021) but these classes are only inlined at compile time. A value class User(val rawName: String) will just become a val rawName: String after compilation. The compiler cannot do anything more until the JDK stabilizes the actual value types byte code.

Kotlin can of course also worsen the performance by compiling to inefficient bytecode, so we should at least look at a couple of performance comparisons.

Execution benchmarking Is tricky

Most business applications are I/O-bound. They receive an Input (usually a web request), do some light processing, write Output to a database, and then Output a response to the web request. This is exactly the situation that reactive streams (JDK 9, 2017), Coroutines and Virtual Threads are trying to solve. But that is not about performance but efficiency. Any I/O-operation means that our application logic is waiting on the result and not doing anything. Reactive Streams/Coroutines/Virtual Threads solve this by using the thread for another operation until the I/O-operation returns a result. Efficient.

In some cases however our application can be CPU-bound. Encoding/decoding of information or multiplying huge matrices are examples of this.

When writing such a CPU-bound code we then often have to make the trade-off between speed and readability. The Java-exclusive one billion row challenge 1BRC shows this rather nicely. We have to read a .txt file with one billion rows of temperature measurements per weather station and calculate the min/mean/max for each weather station. A version that takes about 13 seconds to complete, has 11 functions and comprises about 250 lines of code. It is quite readable. The winner of the challenge however takes about 2 seconds, has 23 functions and 435 lines of code, and manipulates its own memory via sun.misc.Unsafe. It is much less readable.

So when we look at performance benchmarks, note that each result might be made more performant by creating less readable code. All these benchmarks give us is a rough relation between the execution time of these languages.

Benchmarks

Many language benchmarks exist including the Programming Language and compiler benchmarks, the benchmarks game and the energy efficiency benchmark. The one used here is kostya/benchmarks because the code is “written as the average software developer would write it”:

  • The algorithms are implemented as cited in public sources;
  • The libraries are used as described in the tutorials, documentation and examples;
  • The used data structures are idiomatic.

A couple of languages beyond Java and Kotlin are included for reference —including Scala, which also runs on the JVM. ‘Staged’ results are excluded because that is just for testing purposes and not indicative of real-world performance.

bench.b
Execute Brainf***
Base64
encode/decode
Matmul
Multiply matrixes
1,008s Rust0,635s NodeJs3,034s C/gcc
1,112s C/gcc0,842s Rust3,057s Java
1,191s Java1,117s C/gcc3,067s Rust
1,224s Kotlin/JVM1,435s Java3,153s Go
1,256s Go1,561 Kotlin/JVM3,160s Kotlin
1,280s C#/.NET Core1,592s Go3,212s NodeJs
1,594s Scala3,243s Scala
2,379s Scala3,263s Python/pypy
2,954s NodeJs2,374s C#/.NET Core
9,398s Python/pypy3,534s Python/pypy4,506s C#/.NET Core

Verdict

Java and Kotlin provide about the same performance in these benchmarks. In the three benchmarks Java is leading by about 0,1 seconds. For most business applications, maybe all, that difference is negligible.

Mature Libraries and Frameworks

A mature ecosystem has a plethora of libraries and frameworks, giant shoulders we can build upon. Java has a rich catalog of around 800.000 packages for a diverse topics such as web, auth, database, test, serialization, validation and mapping. Kotlin on the JVM has all of those as well. Every Java library can be used in Kotlin, because Kotlin put a heavy emphasis on interop (as we will see in part 3).

A java.util.List in Java is a kotlin.collections.List in Kotlin. A java.util.Map in Java is a kotlin.collections.Map. No conversion necessary. This is different from other JVM languages like Scala or Clojure where the standard libraries are not compatible but need to be converted.

Frameworks like Quarkus and Spring provide first-class support for Kotlin which means a lot of testing on their part. It also means convenience methods to make the framework feel more idiomatic in Kotlin, support for Kotlin coroutines and using JSpecify @Nullable and @NonNull to mark values that can be null or can never be null. The latter means that Kotlins Null safety also works with Java libraries.

Verdict

Kotlin can use exactly the same mature catalogue of libraries and frameworks that Java has. In addition Kotlin has a growing collection of multi-platform libraries that we will see in part 2.

Ecosystem Summary

Should we pick Java or Kotlin? If we look at the ecosystem we get the following table:

CriteriaJavaKotlinComment
Longevity, Pace, Compatibility●●◐●●◐Both are safe long‑term bets. Java has a noticeably slower feature-pace. Kotlin expects developers to continuously update but has very good migration ergonomics.
Developers availability and interest●●●●●◐Java has more practicing developers; Kotlin provides a very good learning curve
Quality IDE Support●●●●●ⓘJetBrains which develops Kotlin, also develops the world-class IntelliJ IDE for Kotlin and Java (if that is your IDE, replace the ⓘ rating with a ●). Kotlin’s LSP is not stable yet, which is a drawback for editor-only developers.
Compile and Runtime performance●●○●●○Both languages have roughly the same compilation and runtime performance. Build tools seem to be the main bottleneck for faster compilation.
Mature Libraries and Frameworks●●●●●●Java has a very large catalogue of libraries and frameworks. Kotlin can use all these libraries because of its great interoperability.

On the JVM alone, Java and Kotlin are similar in expected longevity, mature libraries, compile and runtime performance. Java currently wins in talent availability and breadth of Editor-support; Kotlin wins with pace, ergonomics and migration tooling, especially in JetBrains IDEs. Kotlin pulls far ahead for teams that are stuck on JDK 8 as it provides modern features with familiar syntax to a 12 year old runtime.

Where Kotlin clearly differentiates itself is in multi-platform development as we will see in part 2. In this part we will also look at the multi-platform libraries and frameworks.

In part 3 we will look at how well we can model business problems with both languages and give a final verdict.

This article is part of the JAVAPRO special magazine issue:

Java in the Age of AI

Explore how AI is transforming the way we build, secure, and operate software with Java.
From AI agents and new architectural patterns to security, data, and team dynamics—this edition brings together real-world insights for building intelligent, production-ready systems.

Discover the edition 

Total
0
Shares
Previous Post

BoxLang AI Deep Dive — Part 5 of 7: One API, 17 Providers — The Provider Architecture Deep Dive 🛡️

Next Post

BoxLang AI Deep Dive — Part 6 of 7: Memory Systems & RAG — Building AI That Remembers 🧠

Related Posts