Promoting Kotlin Adoption Within Your Company | Kotlin Blog
# The Ultimate Guide to Successfully Adopting Kotlin in a Java-Dominated Environment
**Part 3 — Growing Kotlin Adoption in Your Company**
*This is the third post in our series, following real teams as Kotlin adoption grows — from one developer’s curiosity to a company-wide transformation.*
**All parts in the series:**
- [Getting Started With Kotlin for Java Developers](https://blog.jetbrains.com/kotlin/2025/10/getting-started-with-kotlin-for-java-developers/)
- [Evaluating Kotlin in Real Projects](https://blog.jetbrains.com/kotlin/2025/10/evaluating-kotlin-in-real-projects/)
- [Growing Kotlin Adoption in Your Company](https://blog.jetbrains.com/kotlin/2025/11/growing-kotlin-adoption-in-your-company/)
---
## Spread the Word: Win the Hearts and Minds of Your Fellow Developers
You now have a **core team convinced of Kotlin’s advantages**. The next step is scaling adoption across your company — and that means winning over skeptical Java developers.
Two broad approaches matter here:
### **Hard Factors: The Code**
- **Let the code speak** — Show concrete, real-world improvements through clear Kotlin examples rather than slides.
### **Soft Factors: Support & Connect Developers**
- **Facilitate onboarding** — Migration guides, starter templates, and pre-configured IDE settings help developers start quickly.
- **Offer self-study resources** — Tutorials, documentation, and curated online courses.
- **Build an in-house Kotlin community** — Internal chat channels, lunch-and-learns, or meetups to share experiences.
- **Be patient** — Allow time for exploration and comfort building; change takes time.
---
## Let the Code Speak
Use your experience from rewriting or launching applications in Kotlin to **demonstrate improvements** everyone can relate to — like:
- Reduced boilerplate
- Improved type safety
- Better null handling
- Cleaner, more concise syntax
---
## **Example 1: Null-Safety — No More Billion-Dollar Mistakes**
### JavaBooking booking = null; // Allowed, but crashes at runtime
booking.destination; // NullPointerException
Optional booking = null; // Also unsafe
booking.map(Destination::destination); // NullPointerException
### Kotlinval booking: Booking? = null // ✅ Nullable type
val booking: Booking = null // ❌ Compile-time error
booking.destination // ❌ Compile error if booking is nullable
booking?.destination // ✅ Safe access
**Key takeaway:** Kotlin enforces null-safety at the *language level*, preventing errors at compile time.
---
### Domain Example
#### Kotlindata class Booking(val destination: Destination? = null)
data class Destination(val hotel: Hotel? = null)
data class Hotel(val name: String, val stars: Int? = null)
#### Javapublic record Booking(Optional destination) { ... }
public record Destination(Optional hotel) { ... }
public record Hotel(String name, Optional stars) { ... }
---
### Constructing and Traversing Objects
#### Kotlinval booking: Booking? = Booking(Destination(Hotel("Sunset Paradise", 5)))
println(booking?.destination?.hotel?.stars)
#### JavaOptional.of(new Booking(
Optional.of(new Destination(
Optional.of(new Hotel("Sunset Paradise", 5))))))
Java needs **wrappers**, verbose chaining, and extra unwrapping for deep object graphs.
---
**Why it matters:** Null-safety and concise syntax reduce runtime crashes and make code far easier to read and maintain.
---
## **Example 2: Collections API That Works With You**
### Java Streamsproducts.stream()
.collect(Collectors.groupingBy(
Product::name,
Collectors.mapping(gp ->
Arrays.stream(gp.ratings()).max().orElse(0),
Collectors.reducing(0, Integer::max)
)
));
### Kotlinval maxRatingsPerProduct = products
.groupBy { it.name }
.mapValues { (_, grouped) ->
grouped.flatMap { it.ratings.asList() }.maxOrNull() ?: 0
}
**Why it's better:**
- Extension methods unify operations across collections
- No `Stream`/`Optional`/`Collectors` complexity
- Same API for arrays, lists, sets, maps
- Readable left-to-right pipelines
---
## **Example 3: No More Checked Exceptions**
Java forces you to declare and catch checked exceptions — often producing noise without safety gains.
### Kotlin Alternativefun downloadAndGetLargestFile(urls: List): String? =
urls.mapNotNull { runCatching { URI(it).toURL() }.getOrNull() }
.maxOfOrNull { it.openStream().use { it.reader().readText() } }
Kotlin uses `runCatching` and nullable types for cleaner, safer code.
---
## **Example 4: Functions as First-Class Citizens**
### Kotlinfun doWithImage(url: URL, f: (String, BufferedImage) -> Unit) =
f(url.file, ImageIO.read(url))
fun debug(msg: () -> String) {
if (isDebugEnabled) logger.debug(msg())
}
debug { "expensive concat".repeat(1000) }
Functions are explicit and type-safe at the declaration site. There's no need to dig through verbose `java.util.function` interfaces.
---
## **Example 5: Coroutines for Headache-Free Concurrency**
Instead of Reactive `Mono/Flux` complexity:
### Kotlinsuspend fun storeUser(user: User): User = coroutineScope {
val avatarUrl = async { avatarService.randomAvatar() }
val validEmail = async { emailService.verifyEmail(user.email) }
if (!validEmail.await()) throw InvalidEmailException("Invalid email")
personRepo.save(user.copy(avatar = avatarUrl.await()))
}
Readable sequential style + real async execution.
---
## **Example 6: Yes, Java is Improving — But Kotlin Is Ahead**
Java is adding **records**, **pattern matching**, and **virtual threads**. Kotlin already offers null safety, concise collections, first-class functions, and unified APIs — years ahead.
---
## **Example 7: Kotlin’s Evolutionary Advantage**
Kotlin’s design:
- Learns from proven paradigms across languages
- Fixes longstanding Java shortcomings
- Maintains full JVM compatibility
---
## Soft Adoption Strategies
### 1. Facilitate Easy Onboarding
- Side-by-side Java/Kotlin sample projects
- Pre-configured lint/test tools (SonarQube, ktlint, detekt)
- Coaching from experienced Kotlin engineers
### 2. Provide Self-Study Materials
- [JetBrains Tour of Kotlin](https://kotlinlang.org/docs/getting-started.html)
- [Kotlin Koans](https://kotlinlang.org/docs/koans.html)
- [Udacity Kotlin Bootcamp](https://www.udacity.com/course/kotlin-bootcamp-for-programmers--ud9011)
### 3. Build an Internal Kotlin Community
- Core group of devs + management support
- Kick-off event with known speakers
- Regular meetups & shared chat/wiki spaces
- Invite external experts for deep-dives
### 4. Be Patient
Adoption is cultural change — **show, don’t tell** — and give space for exploration.
---
## Up Next in the Series
Next: **Convincing Decision Makers**
We’ll cover building a business case for Kotlin adoption, linking developer wins to measurable savings, and making the argument that Kotlin is **strategic** — not just technical.

[*Prev post* — Evaluating Kotlin in Real Projects](https://blog.jetbrains.com/kotlin/2025/10/evaluating-kotlin-in-real-projects/)