Compatibility guide for Kotlin 2.3 Keeping the Language Modern and Comfortable Updates are among the fundamental principles in Kotlin Language Design. The former says that constructs which obstruct language evolution should be removed, and the latter says that this removal should be well-communicated beforehand to make code migration as smooth as possible.
While most of the language changes were already announced through other channels, like update changelogs or compiler warnings, this document summarizes them all, providing a complete reference for migration from Kotlin 2.2 to Kotlin 2.3. This document also includes information about tool-related changes.
Basic terms In this document, we introduce several kinds of compatibility:
source : source-incompatible change stops code that used to compile fine (without errors or warnings) from compiling anymore
binary : two binary artifacts are said to be binary-compatible if interchanging them doesn't lead to loading or linkage errors
behavioral : a change is said to be behavioral-incompatible if the same program demonstrates different behavior before and after applying the change
Remember that those definitions are given only for pure Kotlin. Compatibility of Kotlin code from the other languages perspective (for example, from Java) is out of the scope of this document.
Language Drop support in -language-version for 1.8 and 1.9 Issue : KT-76343 , KT-76344 .
Component : Compiler
Incompatible change type : source
Short summary : Starting with Kotlin 2.3, the compiler no longer supports -language-version=1.8 . Support for -language-version=1.9 is also removed for non-JVM platforms.
Deprecation cycle :
2.2.0: report a warning when using -language-version with versions 1.8 and 1.9
2.3.0: raise the warning to an error for -language-version with version 1.8 on all platforms and for version 1.9 on non-JVM platforms
Report upper-bound constraint violation errors for inferred types with typealiases Issue : KTLC-287
Component : Core language
Incompatible change type : source
Short summary : Previously, the compiler never reported errors about upper-bound violation constraints for the inferred types. This has been fixed in Kotlin 2.3.0 so that the error is reported consistently across all type parameters.
Deprecation cycle :
Prohibit @JvmSerializableLambda annotation on inline and crossinline lambdas Issue : KTLC-9
Component : Core language
Incompatible change type : source
Short summary : You can no longer apply the @JvmSerializableLambda annotation to inline or crossinline lambdas. These lambdas aren't serializable, so applying @JvmSerializableLambda had no effect.
Deprecation cycle :
Prohibit delegating a Kotlin interface to a Java class when the generic signatures don't match Issue : KTLC-267
Component : Core language
Incompatible change type : source
Short summary : Kotlin 2.3.0 forbids delegation to a Java class that implements a generic interface method with a non-generic override. Previously, allowing this behavior led to type mismatches and ClassCastException reported at runtime. This change shifts the error from runtime to compile time.
Deprecation cycle :
Deprecate use of return in expression-bodied functions without explicit return type Issue : KTLC-288
Component : Core language
Incompatible change type : source
Short summary : Kotlin now deprecates using return inside expression bodies when the function's return type isn't explicitly declared.
Deprecation cycle :
Prohibit inheritance from nullable supertypes introduced via typealias Issue : KTLC-279
Component : Core language
Incompatible change type : source
Short summary : Kotlin now reports an error when attempting to inherit from a nullable typealias, which is consistent with how it already handles direct nullable supertypes.
Deprecation cycle :
Unify generic signature generation for top-level lambdas and call arguments Issue : KTLC-277
Component : Reflection
Incompatible change type : behavioral
Short summary : Kotlin 2.3.0 uses the same type-checking logic for top-level lambdas as it does for lambdas passed as call arguments, ensuring consistent generic signature generation across both cases.
Deprecation cycle :
Prohibit reified type parameters from being inferred as intersection types Issue : KTLC-13
Component : Core language
Incompatible change type : source
Short summary : Kotlin 2.3.0 prohibits situations where a reified type parameter is inferred to an intersection type, as this could lead to incorrect runtime behavior.
Deprecation cycle :
Prohibit exposing less-visible types through type parameter bounds Issue : KTLC-275
Component : Core language
Incompatible change type : source
Short summary : Kotlin 2.3.0 forbids using type parameter bounds that expose types with more restrictive visibility than the function or declaration itself, aligning the rules for functions with those already applied to classes.
Deprecation cycle :
Standard library Deprecate Char-to-number conversions and introduce explicit digit and code APIs Issue : KTLC-321
Component : kotlin-stdlib
Incompatible change type : source
Short summary : Kotlin 2.3.0 deprecates Char.toX() and X.toChar() conversions for numeric types and introduces new, explicit APIs for accessing a character's code and digit value.
Deprecation cycle :
1.4.30: introduce new functions as Experimental
1.5.0: promote the new functions to Stable; report warnings for old functions with suggestions for replacements
2.3.0: raise the warnings to errors
Deprecate Number.toChar() function Issue : KT-56822
Component : kotlin-stdlib
Incompatible change type : source
Short summary : The Number.toChar() function is deprecated. Use toInt().toChar() or the Char constructor instead.
Deprecation cycle :
Deprecate String.subSequence(start, end) function Deprecate kotlin.io.createTempDirectory() and kotlin.io.createTempFile() functions Issue : KTLC-280
Component : kotlin-stdlib
Incompatible change type : source
Short summary : After being deprecated for a long time, the InputStream.readBytes(estimatedSize: Int = DEFAULT_BUFFER_SIZE): ByteArray function is now hidden.
Deprecation cycle :
Issue : KT-81431
Component : Kotlin/Native
Incompatible change type : behavioral
Short summary : When formatting an exception stack trace, additional causes aren't printed if the same exception cause has already been printed.
Deprecation cycle :
Correct Iterable<T>.intersect() and Iterable<T>.subtract() behavior Issue : KTLC-268
Component : kotlin-stdlib
Incompatible change type : behavioral
Short summary : The Iterable<T>.intersect() and Iterable<T>.subtract() functions now test membership for each receiver element before adding it to the result set. The result set compares elements using Any::equals, ensuring correct results even when the argument collection uses referential equality (for example, IdentityHashMap.keys).
Deprecation cycle :
Unsupported KGP version warning when using kotlin-dsl and kotlin("jvm") plugins Issue : KT-79851
Component : Gradle
Incompatible change type : behavioral
Short summary : In Kotlin 2.3, if you use both the kotlin-dsl and the kotlin("jvm") plugin in your Gradle project, you may see a Gradle warning about an unsupported Kotlin Gradle plugin (KGP) version.
Migration steps :
In general, we don't recommend using both the kotlin-dsl and the kotlin("jvm") plugins in the same Gradle project. This setup isn't supported.
For convention plugins, precompiled script plugins or any other form of unpublished build logic, you have three options:
Don't apply the kotlin("jvm") plugin explicitly. Instead, let the kotlin-dsl plugin automatically provide a compatible KGP version.
If you want to apply the kotlin("jvm") plugin explicitly, use the embeddedKotlinVersion constant to specify the embedded Kotlin version.
To upgrade the embedded Kotlin and language versions, update your Gradle version. You can find compatible Gradle versions in Gradle's Compatibility Notes for Kotlin .
Don't use the kotlin-dsl plugin. This may be more appropriate for binary plugins that aren't tied to a specific Gradle version.
As a last resort, you can configure your project to use language version 2.1 or higher, which overrides the conflicting behavior of the kotlin-dsl plugin. However, we strongly recommend not doing so.
If you experience difficulties during migration, reach out in the #gradle channel in our Slack for support.
Deprecation cycle :
Deprecate kotlin-android plugin for AGP versions 9.0.0 and later Issue : KT-81199
Component : Gradle
Incompatible change type : source
Short summary : In Kotlin 2.3.0, the org.jetbrains.kotlin.android plugin is deprecated when using Android Gradle plugin (AGP) versions 9.0.0 or later. Starting with AGP 9.0.0, AGP provides built-in support for Kotlin , so the kotlin-android plugin is no longer required.
Deprecation cycle :
Deprecate testApi configuration Issue : KT-63285
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.3.0 deprecates the testApi configuration. This configuration exposed test dependencies and sources to other modules, but Gradle doesn't support this behavior.
Migration options : Replace any instances of testApi() with testImplementation(), and do the same for other variants. For example, replace kotlin.sourceSets.commonTest.dependencies.api() with kotlin.sourceSets.commonTest.dependencies.implementation().
For Kotlin/JVM projects, consider using Gradle's test fixtures instead. If you'd like to see support for test fixtures in multiplatform projects, share your use case in YouTrack .
Deprecation cycle :
Deprecate createTestExecutionSpec() function Issue : KT-75449
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.3.0 deprecates the createTestExecutionSpec() function in the KotlinJsTestFramework interface since it is no longer used.
Deprecation cycle :
Issue : KT-64273
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.3.0 removes the closureTo(), createResultSet() functions from the closure DSL since they are no longer used. In addition, the KotlinToolingVersionOrNull() function is removed. Use the KotlinToolingVersion() function instead.
Deprecation cycle :
Issue : KT-74915
Component : Gradle
Incompatible change type : source
Short summary : The ExtrasProperty API, which has been deprecated since Kotlin 2.0.0, is now internalized in Kotlin 2.3.0. Use Gradle's ExtraPropertiesExtension API as an alternative.
Deprecation cycle :
Deprecate HasKotlinDependencies in KotlinCompilation Issue : KT-67290
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.3.0 deprecates the HasKotlinDependencies interface in KotlinCompilation . Dependency-related APIs are now exposed through the KotlinSourceSet interface instead.
Deprecation cycle :
Deprecate npm and Yarn package manager internal functions and properties Issue : KT-81009
Component : Gradle
Incompatible change type : source
Short summary : The following functions and properties related to the npm and Yarn package managers are deprecated:
CompositeDependency.dependencyName, CompositeDependency.dependencyVersion, CompositeDependency.includedBuildDir.
KotlinNpmInstallTask.Companion.NAME.
LockCopyTask.Companion.STORE_PACKAGE_LOCK_NAME, LockCopyTask.Companion.RESTORE_PACKAGE_LOCK_NAME, LockCopyTask.Companion.UPGRADE_PACKAGE_LOCK.
Npm.npmExec().
NpmProject.require(), NpmProject.useTool().
PublicPackageJsonTask.jsIrCompilation.
YarnBasics.yarnExec().
YarnPlugin.Companion.STORE_YARN_LOCK_NAME, YarnPlugin.Companion.RESTORE_YARN_LOCK_NAME, YarnPlugin.Companion.UPGRADE_YARN_LOCK.
YarnSetupTask.Companion.NAME.
Deprecation cycle :
Deprecate support for PhantomJS Issue : KT-76019
Component : Gradle
Incompatible change type : source
Short summary : Since PhantomJS is no longer maintained, Kotlin 2.3.0 deprecates the karmaPhantomjsLauncher property in the NpmVersions API.
Deprecation cycle :
Prohibit subclassing of classes that set up test runs or JavaScript runtime Issue : KT-75869 , KT-81007
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 2.3.0 prohibits subclassing the following classes:
KotlinTest
KotlinNativeTest
KotlinJsTest
KotlinJsIrTarget
KotlinNodeJsIr
KotlinD8Ir
KotlinKarma
KotlinMocha
KotlinWebpack
TypeScriptValidationTask
YarnRootExtension
These classes were never intended to be subclassed. All use cases for subclassing should now be covered by the configuration blocks provided by the Kotlin Gradle plugin DSL. If the existing APIs for these tasks don't meet your needs for setting up test runs or the JavaScript runtime, share your feedback in YouTrack .
Deprecation cycle :
Deprecate ExperimentalWasmDsl annotation class Issue : KT-81005
Component : Gradle
Incompatible change type : source
Short summary : The ExperimentalWasmDsl annotation class is deprecated since the functionality has moved to the kotlin-plugin-annotations module.
Deprecation cycle :
Deprecate ExperimentalDceDsl annotation class Issue : KT-81008
Component : Gradle
Incompatible change type : source
Short summary : The ExperimentalDceDsl annotation class isn't used anymore, so it's been deprecated.
Deprecation cycle :
Deprecate JavaScript utilities Issue : KT-81010
Component : Gradle
Incompatible change type : source
Short summary : The following functions and properties are only used internally, so they've been deprecated:
JsIrBinary.generateTs
KotlinJsIrLink.mode
NodeJsSetupTask.Companion.NAME
Appendable.appendConfigsFromDir()
ByteArray.toHex()
FileHasher.calculateDirHash()
String.jsQuoted()
Deprecation cycle :
2.2.0: report a warning when the KotlinJsIrLink.mode property is used
2.2.0: report a warning when the NodeJsSetupTask.Companion.NAME property and functions are used
2.2.20: report a warning when the JsIrBinary.generateTs property is used
2.3.0: raise the warnings to errors
Deprecate migrated D8 and Binaryen properties Issue : KT-81006
Component : Gradle
Incompatible change type : source
Short summary : The following properties are deprecated because they've been migrated from the org.jetbrains.kotlin.gradle.targets.js package to the org.jetbrains.kotlin.gradle.targets.wasm package:
binaryen.BinaryenEnvSpec
binaryen.BinaryenExtension
binaryen.BinaryenPlugin
binaryen.BinaryenRootPlugin
BinaryenSetupTask.Companion.NAME
d8.D8EnvSpec
d8.D8Plugin
D8SetupTask.Companion.NAME
Deprecation cycle :
Deprecate create() function in NodeJsExec DSL Issue : KT-81004
Component : Gradle
Incompatible change type : source
Short summary : The create() function in the companion object of the NodeJsExec DSL is deprecated. Use the register() function instead.
Deprecation cycle :
Deprecate properties in kotlinOptions DSL Issue : KT-76720
Component : Gradle
Incompatible change type : source
Short summary : The ability to configure compiler options through the kotlinOptions DSL and the related KotlinCompile<KotlinOptions> task interface has been deprecated in favor of the new compilerOptions DSL since Kotlin 2.2.0. Kotlin 2.3.0 continues the deprecation cycle for all properties in the kotlinOptions interface. To migrate, use the compilerOptions DSL to configure compiler options. For guidance on the migration, see Migrate from kotlinOptions {} to compilerOptions {} .
Deprecation cycle :
2.0.0: report a warning for kotlinOptions DSL
2.2.0: raise the warning to an error and deprecate all properties in kotlinOptions
2.3.0: raise the warning to an error for all properties in kotlinOptions
Deprecate kotlinArtifacts API Issue : KT-77066
Component : Gradle
Incompatible change type : source
Short summary : The experimental kotlinArtifacts API is deprecated. Use the current DSL available in the Kotlin Gradle plugin to build final native binaries . If it's not sufficient for migration, leave a comment in this YouTrack issue .
Deprecation cycle :
Remove kotlin.mpp.resourcesResolutionStrategy Gradle property Issue : KT-74955
Component : Gradle
Incompatible change type : source
Short summary : Previously the kotlin.mpp.resourcesResolutionStrategy Gradle property was deprecated because it wasn't used. In Kotlin 2.3.0, the Gradle property is removed completely.
Deprecation cycle :
Issue : KT-61127
Component : Gradle
Incompatible change type : source
Short summary : Before Kotlin 2.3.0, we supported multiple modes of multiplatform IDE import. Now, the older mode is deprecated, leaving only one mode available. Previously, the old mode was enabled using the kotlin.mpp.import.enableKgpDependencyResolution=false Gradle property. Using this property now triggers a deprecation warning.
Deprecation cycle :
Remove properties to disable precise compilation backup Issue : KT-81038
Component : Gradle
Incompatible change type : source
Short summary : Kotlin 1.9.0 introduced an experimental optimization for incremental compilation called precise compilation backup. After successful testing, this optimization was enabled by default in Kotlin 2.0.0. Kotlin 2.3.0 removes the kotlin.compiler.preciseCompilationResultsBackup and kotlin.compiler.keepIncrementalCompilationCachesInMemory Gradle properties that opt out of this optimization.
Deprecation cycle :
Deprecate destinationDir in CInteropProcess Issue : KT-74910
Component : Gradle
Incompatible change type : source
Short summary : The destinationDir property in the CInteropProcess task is deprecated. Use the CInteropProcess.destinationDirectory.set() function instead.
Deprecation cycle :
2.1.0: report a warning when the destinationDir property is used
2.2.0: raise this warning to an error
2.3.0: hide the destinationDir property
Deprecate konanVersion in CInteropProcess Issue : KT-74911
Component : Gradle
Incompatible change type : source
Short summary : The konanVersion property in the CInteropProcess task is deprecated. Use CInteropProcess.kotlinNativeVersion instead.
Deprecation cycle :
2.1.0: report a warning when the konanVersion property is used
2.2.0: raise this warning to an error
2.3.0: hide the konanVersion property
Remove KotlinCompile.classpathSnapshotProperties properties Issue : KT-76177
Component : Gradle
Incompatible change type : source
Short summary : The kotlin.incremental.useClasspathSnapshot Gradle property was removed in Kotlin 2.2.0. In Kotlin 2.3.0, the following properties are also removed:
Deprecation cycle :
2.0.20: deprecate the kotlin.incremental.useClasspathSnapshot property with a warning
2.2.0: remove the kotlin.incremental.useClasspathSnapshot property
2.3.0: remove the KotlinCompile.classpathSnapshotProperties.useClasspathSnapshot and KotlinCompile.classpathSnapshotProperties.classpath properties
Deprecate getPluginArtifactForNative() function 05 November 2025