Anna Kowalski, YuSMP Group
Anna Kowalski Senior Mobile Engineer, YuSMP Group · React Native, Flutter and native iOS/Android since 2015

Short answer first: for a new Android app in 2026, choose Kotlin. Google has been Kotlin-first since 2019, Jetpack Compose only works with Kotlin, and most new Android libraries are designed around coroutines and Kotlin extensions. Java is still fully supported, though, and for a large, stable Java codebase the right move is rarely a rewrite — it is a gradual, well-planned mix of both languages.

That is also how we frame the Kotlin vs Java question when we scope mobile app development projects. For greenfield work the decision takes minutes. For companies with five or ten years of Java in their Android app, the real questions are different: what does staying on Java cost, what does migration cost, and how do you migrate without freezing the roadmap? Those are the questions most comparisons skip, and they are the focus of the second half of this guide.

This article is about the language choice inside Android. If you are still deciding which platform to launch on, read iOS vs Android: which platform to launch first; for the process and cost of building an Android product end to end, see our Android software development guide or our Android app development service.

TL;DR: Kotlin or Java for Android?

Use Kotlin for any new Android app or feature: Jetpack Compose, coroutines and Google’s Kotlin-first tooling all assume it. Java remains a sound choice for stable legacy modules, JVM libraries shared with a Java backend, and Java-only teams maintaining an app with a short horizon. Most real-world apps end up mixed — and that is fine.

  • Google’s position is explicit. Android has been Kotlin-first since Google I/O 2019; Java stays supported for the SDK, Android Studio and AndroidX.
  • Compose is the hard line. Jetpack Compose, KTX extensions and coroutine-based Jetpack APIs are Kotlin-only.
  • Performance is not the deciding factor. Both languages compile to the same bytecode and run on ART; the K2 compiler has sharply reduced Kotlin build times.
  • Migration does not mean a rewrite. Full interoperability lets you add Kotlin file by file while the app keeps shipping.

What is Kotlin for Android development?

Kotlin is a statically typed programming language created by JetBrains, the company behind IntelliJ IDEA (on which Android Studio is built). It runs on the Java Virtual Machine, compiles to the same bytecode as Java and can call any Java library directly. On Android, that bytecode goes through the same D8/R8 toolchain and runs on the Android Runtime (ART), exactly like Java code.

At Google I/O 2019, Google announced that Android development would be Kotlin-first: new tools, Jetpack libraries, samples and documentation are designed with Kotlin users in mind, while Google continues to support using its APIs from Java. Google also reports that more than 70 of its own apps — including Maps, Home, Play, Drive and Messages — use Kotlin.

For Android teams, Kotlin’s value comes from a handful of features that map directly to everyday problems:

  • Null safety in the type system. A String cannot be null; a String? can, and the compiler forces you to handle it. This removes most accidental NullPointerExceptions at compile time.
  • Coroutines and Flow. Structured concurrency for network calls, database access and UI state, with lifecycle-aware scopes such as viewModelScope.
  • Concise, expressive syntax. Data classes, extension functions, default arguments, sealed classes and smart casts cut much of the boilerplate that Java code carries.
  • Jetpack Compose. Android’s modern declarative UI toolkit is built on a Kotlin compiler plugin.

The language itself keeps moving. The K2 compiler became stable and the default in Kotlin 2.0.0, rebuilding the compiler front end for speed and a single, consistent architecture across platforms. That matters for Android teams because build time was historically the most common complaint about Kotlin.

What is Java for Android development today?

Java was Android’s original language, and it is still a first-class, supported option. According to Google’s own support matrix, the platform SDK, Android Studio, Lint, the API reference and the AndroidX libraries all support both Java and Kotlin. Millions of lines of production Android code are written in Java, many widely used SDKs still ship Java APIs, and a Java developer can open a modern Android project and be productive in the non-Compose parts of it.

What Java does not get is the newest layer of the stack. Jetpack Compose, the Kotlin extensions (KTX) and coroutine-based APIs are Kotlin-only, and new samples and codelabs are written in Kotlin first. In practice, a Java-only Android app in 2026 is built on Views and XML layouts, uses threads, executors, CompletableFuture or RxJava for asynchronous work, and relies on annotations such as @Nullable and @NonNull for null hints.

Which Java version can you actually use on Android?

This is where many comparisons go wrong. Android does not run “the latest Java”. It runs its own implementation of the Java core libraries, and the version depends on the Android release and your build tools. According to Google’s documentation on Java versions in Android builds:

  • Android 14 (API 34) core libraries are based on Java 17; Android 12 and 13 are based on Java 11.
  • Desugaring in the Android Gradle Plugin lets you use some newer Java language features and APIs on older devices, by rewriting them at build time.
  • Android Gradle Plugin 8.x requires JDK 17 to run the build. Android Studio ships its own JDK, the JetBrains Runtime (JBR).
  • You set the toolchain in Gradle, for example with java { toolchain { languageVersion = JavaLanguageVersion.of(17) } }.

So a Java Android developer works with a subset of modern Java that is tied to AGP, desugaring and the minSdk of the app — not with the newest desktop JDK. Kotlin sidesteps much of this, because most of its language features are implemented by the Kotlin compiler and standard library rather than by the device’s Java runtime.

Kotlin vs Java: head-to-head comparison table

The table summarises how the two languages compare on the criteria that actually affect Android projects. Detailed reasoning for each row follows in the sections below.

CriterionKotlinJava
Google’s official stanceKotlin-first since 2019; new tools and docs designed for KotlinFully supported for SDK, Android Studio and AndroidX
UI toolkitJetpack Compose and ViewsViews and XML layouts only
Null safetyBuilt into the type system, checked at compile timeAnnotations and static analysis; not enforced by the language
Asynchronous codeCoroutines and Flow, lifecycle-aware scopesThreads, executors, CompletableFuture, RxJava
BoilerplateData classes, default arguments, extension functionsMore verbose; records and other newer features depend on your Android toolchain, or Lombok
Build speedMuch improved with the K2 compiler (Kotlin 2.0+)javac is typically fast for pure-Java modules
Runtime performanceSame bytecode, DEX and ART pipelineSame bytecode, DEX and ART pipeline
InteroperabilityCalls any Java code directlyCalls Kotlin code; some Kotlin features need annotations to look natural from Java
Learning curveEasy for Java developers to start; idiomatic Kotlin takes practiceFamiliar to most developers; fewer concepts, more code
Talent poolThe standard skill for Android specialistsLarger overall JVM pool, mostly backend
Code sharing beyond AndroidKotlin Multiplatform shares logic with iOS, desktop and serverNo equivalent for iOS; sharing only with JVM backends

Read the table as a map of trade-offs rather than a scoreboard. Kotlin wins the rows that matter for new Android work; Java’s strengths are familiarity, a stable existing codebase and alignment with JVM backends.

How do Kotlin and Java differ in code?

Two short examples show where most of the day-to-day difference comes from. First, a simple data model with an optional field.

Kotlin:

data class User(val name: String, val email: String?)

Java:

public final class User {
    @NonNull private final String name;
    @Nullable private final String email;

    public User(@NonNull String name, @Nullable String email) {
        this.name = name;
        this.email = email;
    }

    @NonNull public String getName() { return name; }
    @Nullable public String getEmail() { return email; }

    // plus equals(), hashCode() and toString()
}

The Kotlin line gives you the constructor, getters, equals(), hashCode(), toString() and copy(), and the ? makes the compiler enforce null checks on email everywhere it is used. The Java version needs annotations for the same hint, and the compiler does not enforce it. Java records shorten this where your Android toolchain supports them, but they do not add null safety.

Second, loading data off the main thread in a ViewModel.

Kotlin (coroutines):

fun loadUser(id: String) {
    viewModelScope.launch {
        val user = repository.getUser(id)   // suspend function, runs off the main thread
        _state.value = UiState.Loaded(user)
    }
}

Java (executor and callback):

void loadUser(String id) {
    executor.execute(() -> {
        User user = repository.getUser(id);
        mainHandler.post(() -> state.setValue(new UiState.Loaded(user)));
    });
}

The Java version works, but cancellation when the screen closes, error handling and chaining several calls are all left to you. With coroutines, the viewModelScope cancels work automatically when the ViewModel is cleared, and sequential asynchronous code reads like ordinary sequential code. Across a whole app, this is where Kotlin’s productivity gains come from.

Is Kotlin faster than Java on Android?

At runtime, for typical apps, neither language is meaningfully faster. Both compile to JVM bytecode, D8 converts that bytecode to DEX, R8 shrinks and optimizes it, and ART runs it with the same just-in-time and ahead-of-time compilation. Performance differences come from how code is written — unnecessary allocations, heavy lambdas in hot loops, inefficient collections — not from the language on the file extension.

Where Kotlin can show measurable benefits is stability, which users experience as quality. Google reports that apps containing Kotlin code are 20% less likely to crash, and that the Google Home team, after moving new feature development to Kotlin, saw a 33% smaller codebase and 30% fewer NullPointerException crashes. These are Google’s own figures from its Kotlin-first page, not independent benchmarks, but they match what null safety is designed to do.

What about build times?

Build time is the performance argument that used to favour Java, and it has narrowed considerably. With Kotlin 2.0.0, the K2 compiler became stable and the default. JetBrains’ K2 benchmarks show up to 94% faster clean builds; on the open-source Anki-Android project, a clean build went from 57.7 seconds with Kotlin 1.9.23 to 29.7 seconds with Kotlin 2.0.0. The initialization phase was up to 488% faster and the analysis phase up to 376% faster.

Two practical notes. First, javac is still typically quick for modules that are pure Java, so a mixed project can see longer builds in modules where Kotlin and Java files depend on each other. Second, annotation processing is often a bigger build cost than the language itself: moving from kapt to KSP (Kotlin Symbol Processing, created by Google) for libraries such as Room and Hilt usually brings a noticeable improvement.

Does Jetpack Compose require Kotlin?

Yes. Jetpack Compose is Kotlin-only. Google’s support matrix lists Compose, the KTX extensions, coroutine-based APIs and compiler plugins such as KSP as Kotlin-only, while the platform SDK, Android Studio, Lint and AndroidX support both languages.

Compose depends on a Kotlin compiler plugin that transforms @Composable functions, so there is no way to write Compose UI in Java files. That does not lock Java apps out of Compose, though. Because the two languages interoperate, a Java app can add Kotlin to the project, write new screens in Compose and host them next to existing View-based screens. Many teams use Compose as the reason to start introducing Kotlin in the first place.

When should you choose Kotlin?

Kotlin is the default choice for most Android work today. These are the situations where we recommend it without hesitation:

  • A new app or a new product line. With no legacy code to protect, there is no reason to start outside the language that Google’s tools, libraries and documentation are designed for.
  • You want Jetpack Compose. If a modern declarative UI, faster UI iteration and a shared design system are on the roadmap, Kotlin is required.
  • The app is heavy on networking, sync or real-time data. Coroutines and Flow make concurrent, cancellable, lifecycle-aware code much simpler than executors or callbacks.
  • You plan to share code with iOS. Kotlin Multiplatform lets you share business logic, networking and data layers with an iOS app, which Java cannot do.
  • Crash rate and long-term maintenance matter. For long-lived products, compile-time null safety and less boilerplate reduce defects and review effort; Google’s data on fewer crashes in Kotlin apps points the same way.

When does Java still make sense?

Choosing Java in 2026 is not a mistake when it follows from real constraints. These are the cases where staying on Java, fully or partly, is reasonable:

  • A large, stable Java codebase in maintenance mode. If the app works, changes rarely and has no major roadmap, converting it adds risk without adding user value. Keep it in Java and write any genuinely new features in Kotlin.
  • Libraries shared with a Java backend. Some companies share validation rules, domain models or SDKs between an Android app and a Java server. Keeping those modules in Java can be the simplest option; our guide to working with a Java development company covers the backend side of that setup.
  • A Java-only team with a short-lived app. For an internal tool or a campaign app that will live for a year, retraining the team may not pay back.
  • Vendor SDKs and generated code. Third-party SDKs, generated API clients and some device-integration layers are written in Java. There is no need to convert code you do not own.
  • Regulated modules with costly re-certification. In banking, medical or payment apps, rewriting a validated module can trigger new audits. Leave it in Java until it needs to change for other reasons.

Notice that none of these is an argument for writing new Android features in Java. They are arguments for not rewriting existing Java code without a reason.

How to migrate a Java Android app to Kotlin without a rewrite

This is the section most Kotlin vs Java comparisons leave out, and for companies with an existing app it is the one that matters. Because Kotlin and Java are fully interoperable, you can mix .java and .kt files in the same module and add Kotlin to an existing app gradually. The app keeps shipping while the language changes underneath it.

Modules replaced one by one, illustrating incremental Java-to-Kotlin migration
Incremental migration replaces modules one at a time while the app stays in production.

The playbook we use follows the same logic as Google’s guide on adopting Kotlin for large teams:

  1. Add the Kotlin plugin and keep modules mixed. Configure Kotlin in Gradle, align the JVM target with your Java toolchain and confirm that the existing build and tests still pass. Nothing else changes yet.
  2. Write all new code in Kotlin. From this point, every new class, screen and feature is Kotlin. This alone moves the codebase steadily without any conversion work.
  3. Start with tests and data classes. Unit tests and model classes are low-risk places to learn Kotlin idioms, and data classes remove the most boilerplate.
  4. Convert with the IDE, then refine by hand. In Android Studio, use Code > Convert Java File to Kotlin File. The output is functionally equivalent but not idiomatic: review nullability, replace unnecessary !!, decide where lateinit is appropriate, and simplify.
  5. Annotate the remaining Java. Add @Nullable and @NonNull to Java APIs that Kotlin code calls, so Kotlin sees real nullable or non-null types instead of uncertain “platform types”.
  6. Introduce coroutines at the ViewModel and repository layers. Replace callbacks and RxJava chains gradually, starting with new flows, and keep adapters where the two worlds meet.
  7. Add Compose screen by screen. Build new screens in Compose and replace old View-based screens when they need significant changes anyway, using Compose–View interoperability in between.

The rule that makes this work is simple: convert code when you touch it for a real reason, not for the sake of conversion. That spreads the cost across normal feature work and keeps the risk small at every step. It is the same principle we apply to legacy system modernization in general.

Common migration pitfalls

  • Platform types. Kotlin cannot know whether unannotated Java returns null. Treat every unannotated Java value as nullable until proven otherwise, or crashes simply move from Java to Kotlin.
  • kapt vs KSP. Keeping kapt for annotation processing after adding Kotlin can make builds slower. Move libraries that support KSP to KSP early.
  • Mixed-module build times. Modules with tight Kotlin–Java cycles compile in several passes. Converting a module fully, or splitting it, often speeds up the build.
  • Inconsistent style. Without shared conventions, each developer writes a different “Kotlin”. Agree on a style guide, enable a linter such as ktlint or detekt, and review converted files carefully.
  • Java callers of Kotlin code. Default arguments, companion objects and top-level functions look awkward from Java. Use @JvmOverloads, @JvmStatic and @JvmName where Java code still calls into Kotlin, as described in the Kotlin–Java interop documentation.

How much does it cost: Kotlin vs Java, new build vs migration?

The language itself does not change hourly rates much: Android engineers today are expected to know Kotlin, and experienced ones read Java comfortably. What changes cost is how much work the language removes or adds over the life of the app. For concrete budgets and timelines, see our breakdown of mobile app development cost in 2026 and our guide on how long it takes to build a mobile app. Here we focus on the drivers.

  • New builds: Kotlin with Compose and coroutines usually shortens UI and asynchronous work, and it aligns the project with current libraries, so there is no reason to budget a new app in Java.
  • Migration: cost scales with the number of modules, the amount of UI written in Views, and test coverage. Good tests make conversions cheap and safe; poor coverage makes every conversion a manual verification task.
  • Incremental vs big-bang: an incremental migration spreads cost over regular releases and rarely needs a dedicated budget line. A full rewrite concentrates cost and risk and delays new features, which is why we seldom recommend it.
  • Cost of standing still: staying on Java has no upfront cost, but new Jetpack features, samples and hiring increasingly assume Kotlin, so maintenance gradually becomes more expensive.
ScenarioRecommended pathMain cost and timeline driver
New Android appKotlin + Jetpack Compose from day oneFeature scope and design, not the language
Legacy Java app, stable, few changes plannedStay on Java; any new code in KotlinMinimal; mostly the Kotlin setup and team conventions
Legacy Java app with an active roadmapIncremental migration alongside feature workModule count, test coverage, amount of View-based UI
Java backend with shared JVM librariesKotlin for Android UI and app layers; shared libraries stay Java or move laterCoordination between backend and mobile teams

What about Kotlin Multiplatform and cross-platform options?

Kotlin has one more advantage that Java cannot match on mobile: Kotlin Multiplatform (KMP). With KMP, you can write business logic, networking, data storage and validation once in Kotlin and use it in both an Android app and an iOS app, while each platform keeps its own native UI. For companies with native Android and iOS apps, it is a practical way to stop implementing the same rules twice. Java has no equivalent for iOS.

If your goal is to share the user interface as well, the comparison changes: then you are looking at cross-platform frameworks rather than Android languages. Our React Native vs Flutter comparison and the broader guide to native vs cross-platform app development cover that decision.

Decision checklist: 7 questions to settle Kotlin vs Java

Answer these for your project. If most answers point to Kotlin, start or continue the move; if several strong answers point to Java, keep existing Java code where it is and write only new code in Kotlin.

  1. Is this a new app or a new major feature? Yes → Kotlin.
  2. Do you want Jetpack Compose now or in the next year? Yes → Kotlin, at least for the UI layer.
  3. How much Java code do you have, and how often does it change? Large and rarely changed → leave it in Java. Large and actively developed → migrate incrementally.
  4. How good is your test coverage? Good → conversions are cheap and safe. Weak → add tests before converting critical modules.
  5. Do you share libraries with a Java backend? Yes → keep shared modules in Java for now; use Kotlin for app-specific code.
  6. Do you plan to share logic with an iOS app? Yes → Kotlin, with Kotlin Multiplatform in mind.
  7. What does your team know, and who will you hire? Android specialists today expect Kotlin; a Java-only team will need a short ramp-up, which is usually quick.

How YuSMP Group approaches the Kotlin vs Java choice

For new Android work, we default to Kotlin with Jetpack Compose and coroutines. For existing Java apps, we don’t push a rewrite. We start with a short audit — module structure, build setup, test coverage, UI layer and the roadmap for the next year — and then agree on a migration order that follows real feature work. Often the first Kotlin code is a new Compose screen or a new repository layer, and the rest follows as the team touches old modules.

When the Android app is one part of a larger legacy estate, the migration becomes part of a wider software modernization plan, so that the app, its APIs and the backend move in a consistent direction.

FAQ

Is Kotlin better than Java for Android in 2026?

For new Android work, yes in most cases. Google has been Kotlin-first since 2019, Jetpack Compose and many Jetpack KTX and coroutine APIs are Kotlin-only, and Kotlin's null safety removes a common class of crashes. Java is still fully supported and remains a reasonable choice for stable legacy modules and shared JVM libraries, so the practical answer for many teams is Kotlin for new code and gradual migration for the rest.

Is Java still supported for Android development?

Yes. The Android platform SDK, Android Studio, Lint, the API documentation and AndroidX libraries all support Java alongside Kotlin, and Google continues to provide support for calling its APIs from Java. What Java does not get is Jetpack Compose and the Kotlin-only extensions such as KTX and coroutine-based APIs.

Can I use Jetpack Compose with Java?

Not directly. Jetpack Compose is a Kotlin-only toolkit, because it relies on a Kotlin compiler plugin. A Java app can still adopt Compose by adding Kotlin to the project and writing the new Compose screens in Kotlin files, while the existing Java screens keep using Views and XML layouts.

Is Kotlin faster than Java at runtime?

For typical apps, there is no meaningful difference. Kotlin and Java both compile to JVM bytecode, which is then converted to DEX and run by the Android Runtime (ART), so the same optimizations apply to both. Differences come from how code is written, for example extra allocations in lambdas or collections, not from the language choice itself.

Can Kotlin and Java be used in the same Android project?

Yes. Kotlin is fully interoperable with Java, and you can mix .java and .kt files in the same module. Kotlin code can call Java classes and Java code can call Kotlin classes, which is exactly what makes gradual migration possible without a rewrite.

How long does it take to migrate a Java app to Kotlin?

It depends on the size of the codebase, test coverage and how actively the app is being developed. Most teams do not migrate in one project: they write all new code in Kotlin and convert existing files when they touch them, so the migration runs alongside normal feature work over months rather than as a separate rewrite with a fixed end date.

Should beginners learn Kotlin or Java for Android?

Kotlin. Current Android documentation, codelabs, samples and Jetpack Compose are Kotlin-first, so a beginner learning Android today will follow the official path more easily in Kotlin. Basic Java knowledge is still useful for reading older code, libraries and Stack Overflow answers.

Which Java version does Android support?

It depends on the Android version and your build tools rather than the latest desktop JDK. Android 14 (API 34) core libraries are based on Java 17 and Android 12 and 13 on Java 11, while desugaring in the Android Gradle Plugin lets you use some newer Java APIs on older devices. Android Gradle Plugin 8.x also requires JDK 17 to run the build.

Does Kotlin increase app size?

Slightly. A Kotlin app includes parts of the Kotlin standard library that a pure Java app does not need. In release builds, R8 code shrinking removes unused classes and methods, so for most production apps the difference is small compared with images, native libraries and third-party SDKs.

Verdict: Kotlin vs Java for Android

In 2026, the Kotlin vs Java decision for Android is settled for new work and nuanced for existing work. Kotlin is where Google, Jetpack and the Android community are going; Java is supported, stable and still present in a large share of real codebases.

  • Choose Kotlin for new apps, new features, anything built with Jetpack Compose, async-heavy code and projects that may share logic with iOS through Kotlin Multiplatform.
  • Keep Java for stable legacy modules, libraries shared with a Java backend, vendor code and regulated modules where a rewrite would trigger costly re-certification.
  • Migrate incrementally if you have a Java app with an active roadmap: new code in Kotlin, conversions when you touch a file, Compose screen by screen.

If you are unsure where your app sits, a short audit of your modules, tests and roadmap usually gives a clear answer within days — and a migration plan that doesn’t stop your releases.