Skip to content
Journal

Business · Hiring

How to Hire a Kotlin Developer in 2026: Android, Coroutines, and the JVM Backend

Kotlin is the default language for Android and a growing choice for JVM backend work. This guide explains what to screen for, how Kotlin-specific skills differ from Java, and what the role actually requires.

Aman Chaudhary

Aman Chaudhary

7 min read

How to Hire a Kotlin Developer in 2026: Android, Coroutines, and the JVM Backend

Sponsored

Share

Kotlin is the default language for Android development. Google made it the preferred language in 2019, and the Android ecosystem has followed: the official documentation is Kotlin-first, the Jetpack libraries are Kotlin-first, and Jetpack Compose, the modern UI toolkit, requires Kotlin. A developer who pitches Java experience for an Android role in 2026 needs to explain how their Java knowledge applies, because the role they are interviewing for is almost certainly a Kotlin codebase.

That is not the only context for the language. Kotlin has also been gaining adoption on the server side, with JetBrains’ own Ktor framework and strong first-party support in Spring Boot. And Kotlin Multiplatform, which reached stable status in late 2023, is being used to share business logic across Android and iOS. The role you are hiring for determines what to screen for, but the Kotlin-specific skills are what the screen has to find.

The null safety screen

Kotlin’s null safety is one of the language’s most-cited features. The type system distinguishes between nullable types (String?) and non-nullable types (String) at compile time, which catches a class of bugs that would only surface at runtime in Java.

Ask this: “What can still cause a NullPointerException in Kotlin, even with null safety?”

Weak candidates say “nothing” and move on. Strong candidates name at least two of the following:

Java interop. Kotlin code that calls Java APIs receives platform types, annotated as String! in the IDE, which means the type system cannot guarantee non-nullability. Calling a Java method that returns null into a non-nullable Kotlin type causes a NullPointerException at the cast site. The fix is to treat Java API return values as nullable and handle them explicitly.

lateinit var. Kotlin allows declaring a non-nullable property as lateinit var, which defers initialization. If you read a lateinit property before it has been set, the runtime throws an UninitializedPropertyAccessException (a subclass of RuntimeException, not exactly an NPE but effectively the same outcome). The idiomatic alternative for properties with lazy initialization is by lazy { }.

!! (non-null assertion). The double-bang operator asserts that a nullable value is non-null and throws a NullPointerException if it is not. It is the explicit escape hatch from the null safety system. Production code should rarely use it; seeing it in a candidate’s code is a reason to ask why.

A developer who knows these three edge cases has worked seriously with Kotlin, not just read the introduction.

Coroutines and structured concurrency

Kotlin coroutines are the language’s approach to asynchronous programming. They are central to Android development (the Jetpack lifecycle-aware coroutine scopes, viewModelScope, and lifecycleScope are the standard way to manage async work) and to Ktor on the backend. A Kotlin developer who does not understand coroutines is missing a core part of the language.

Ask: “What is a suspend function and how does it work?”

The answer: a function marked with suspend can be paused and resumed without blocking a thread. When a suspend function calls another suspend function that waits for IO (a database query, an HTTP request), the coroutine yields the thread to other work and resumes when the result is available. This is cooperative, not preemptive. The call stack is saved as a continuation object on the heap rather than the stack.

Ask a follow-up: “What is structured concurrency, and why does it matter?”

Structured concurrency ties the lifecycle of coroutines to a scope. When a CoroutineScope is cancelled or completes, all coroutines launched within it are cancelled automatically. This prevents coroutine leaks, which in Android would mean work continuing after the user has navigated away from a screen. The Android equivalent is: when viewModelScope is cleared, all coroutines in that scope are cancelled. A developer who has managed coroutine lifecycles manually without structured concurrency has had to handle cancellation themselves, which is error-prone.

Then ask about Flow vs suspend functions. The distinction: a suspend fun returns one value. Flow emits multiple values over time, asynchronously. Use suspend fun for a network call that returns one response. Use Flow for a database query that should re-emit when the underlying data changes, or for a stream of user events. StateFlow and SharedFlow are hot variants of Flow used for UI state and shared event streams in Android architecture.

The Jetpack Compose question (Android roles)

If the role involves Android UI, Jetpack Compose is the modern toolkit. Ask: “What is the difference between recomposition and the composition itself? When does a Composable function recompose?”

The answer: composition is the initial pass where Compose builds the UI tree. Recomposition is what happens when state changes. Compose tracks which state variables a composable function reads and schedules recomposition for only those composables, not the entire tree. A composable recomposes when any State object it reads changes.

The follow-up: “What is the role of remember and what happens if you forget it?”

remember stores a value across recompositions. If you create an object inside a composable without remember, it is recreated on every recomposition. For expensive objects or objects with identity that matters (like a coroutine scope or an animation state), that is a bug, not just inefficiency.

Kotlin Multiplatform (worth asking about)

Kotlin Multiplatform became stable in November 2023. It allows sharing business logic (data models, repositories, use cases) across Android and iOS while keeping the UI native on each platform.

If your product ships on both platforms, KMP experience is worth asking about. The key question is what they share and what they do not. A well-designed KMP codebase shares the domain and data layers and keeps platform-specific code (UI, camera, push notifications) in the platform modules. Someone who has done KMP production work can talk about the commonMain, androidMain, and iosMain source sets, how expect/actual declarations work for platform-specific implementations, and how the iOS Kotlin framework is consumed from Swift code.

Backend Kotlin: what changes

If the role is backend with Kotlin rather than Android, the relevant skills shift. Coroutines still apply. The web framework knowledge changes.

Ktor is JetBrains’ own Kotlin-native HTTP framework. It is lighter than Spring and idiomatic to Kotlin: route definitions use coroutines directly, plugins use Kotlin DSL. If the team runs Ktor, ask the candidate to walk through setting up a route with authentication and dependency injection. Ktor’s dependency injection story is thinner than Spring’s; teams often combine it with Koin or manual DI.

Spring Boot with Kotlin is the other common choice. Spring has strong Kotlin support including extension functions for the template APIs and coroutine support for reactive components. Ask the candidate what Spring Boot features they would configure differently in Kotlin vs Java. A developer who has used Spring Boot with Kotlin knows about the @ConfigurationProperties Kotlin extensions, the kotest Spring integration, and the differences in how Spring handles Kotlin data classes for serialization.

The team question

Ask why they prefer Kotlin over Java. The answer is usually about conciseness (data classes, extension functions, null safety) and coroutines. If they cannot articulate a preference, they may not have made a deliberate choice.

Ask what they find awkward about Kotlin. A developer with real experience will have opinions: the SAM conversion rules are occasionally surprising, the interaction between Kotlin generics and Java generics is sometimes confusing, and the by lazy vs lateinit decision requires judgment. Someone who says “nothing, Kotlin is great” has either not thought about it or wants to give you the answer they think you want.

The skill set intersects with how we screen Android developers more broadly. The how to hire an Android developer guide covers the platform-side knowledge (device fragmentation, Play Store, lifecycle management) that complements the Kotlin screen here.

Frequently asked questions

Can a Java developer transition to Kotlin quickly?
Yes, with a caveat. The syntax is learnable in days. The idiomatic Kotlin mindset takes longer. A Java developer who has never used coroutines will need time to internalize structured concurrency. A developer who has spent years writing Java with mutable state will need to adjust to preferring val over var and using immutable data classes. Most experienced Java developers can be productive in Kotlin within a few months, but verify whether your timeline allows for that ramp-up.
What is the difference between Kotlin coroutines and Java virtual threads?
Both solve the problem of running many concurrent IO-bound tasks without blocking OS threads. Java virtual threads (Project Loom, stable in Java 21) let you write blocking code that the JVM schedules efficiently. Kotlin coroutines use cooperative suspension, meaning a suspend function yields control explicitly rather than blocking. Kotlin coroutines also provide structured concurrency through CoroutineScope, which ties coroutine lifetimes to a parent scope, making cancellation and error propagation predictable. They are different models that reach similar outcomes for IO-bound work.
Should we use Kotlin for a new JVM backend service?
It is a reasonable choice, especially if your team already knows Kotlin from Android work. Ktor is a purpose-built Kotlin web framework that is lightweight and idiomatic. Spring Boot has strong Kotlin support and many Kotlin-specific extensions. The talent pool for JVM backend is still larger in Java, which matters for hiring. If the team has existing Kotlin experience and the service is greenfield, Kotlin is fine. If you are starting from scratch with a team that knows Java, there is no urgent reason to switch.
What salary range should I expect for a Kotlin Android developer?
A mid-level Android developer with 3-5 years of Kotlin experience in the US runs $120,000 to $160,000. Senior engineers with Jetpack Compose, architecture patterns (MVI, MVVM), and production release experience run $160,000 to $210,000. Kotlin backend specialists command rates closer to Java backend engineers. For remote hiring options and cost comparison, see the [developer hiring cost breakdown](/blog/what-it-costs-to-hire-a-developer-2026/).

Sources

Sponsored

Sponsored

Discussion

Join the conversation.

Comments are powered by GitHub Discussions. Sign in with your GitHub account to leave a comment.

Sponsored