Kotlin Help

What's new in Kotlin 1.8.20-RC2

Release date: March 23, 2023

The Kotlin 1.8.20-RC2 release is out! Here are some highlights from this preview version of Kotlin:

IDE support

The Kotlin plugins that support 1.8.20-RC2 are available for:


Supported versions

IntelliJ IDEA

2022.2.x, 2022.3.x

Android Studio

Flamingo (222)

New Kotlin K2 compiler updates

The Kotlin team continues to stabilize the K2 compiler. As mentioned in the Kotlin 1.7.0 announcement, it's still in Alpha. This release introduces further improvements on the road to K2 Beta.

Starting with this 1.8.20-RC2 release, the Kotlin K2 compiler:

Learn more about the new compiler and its benefits in the following videos:

How to enable the Kotlin K2 compiler

To enable and test the Kotlin K2 compiler, use the new language version with the following compiler option:

-language-version 2.0

You can specify it in your build.gradle(.kts) file:

kotlin { sourceSets.all { languageSettings { languageVersion = "2.0" } } }

The previous -Xuse-k2 compiler option has been deprecated.

Leave your feedback on the new K2 compiler

We'd appreciate any feedback you may have!

New Kotlin/Wasm target

Kotlin/Wasm (Kotlin WebAssembly) goes Experimental in this preview release. The Kotlin team finds WebAssembly to be a promising technology and wants to find better ways for you to use it and get all of the benefits of Kotlin.

WebAssembly binary format is independent of the platform because it runs using its own virtual machine. Almost all modern browsers already support WebAssembly 1.0. To set up the environment to run WebAssembly, you only need to enable an experimental garbage collection mode that Kotlin/Wasm targets. You can find detailed instructions here: How to enable Kotlin/Wasm.

We want to highlight the following advantages of the new Kotlin/Wasm target:

  • Faster compilation speed compared to the wasm32 Kotlin/Native target, since Kotlin/Wasm doesn't have to use LLVM.

  • Easier interoperability with JS and integration with browsers compared to the wasm32 target, thanks to the Wasm garbage collection.

  • Potentially faster application startup compared to Kotlin/JS and JavaScript because Wasm has a compact and easy-to-parse bytecode.

  • Improved application runtime performance compared to Kotlin/JS and JavaScript because Wasm is a statically typed language.

Starting with the 1.8.20-RC2 preview release, you can use Kotlin/Wasm in your experimental projects. We provide the Kotlin standard library (stdlib) and test library (kotlin.test) for Kotlin/Wasm out of the box. IDE support will be added in future releases.

Learn more about Kotlin/Wasm in this YouTube video.

How to enable Kotlin/Wasm

To enable and test Kotlin/Wasm, update your build.gradle.kts file:

plugins { kotlin("multiplatform") version "1.8.20-RC2" } kotlin { wasm { binaries.executable() browser { } } sourceSets { val commonMain by getting val commonTest by getting { dependencies { implementation(kotlin("test")) } } val wasmMain by getting val wasmTest by getting } }

To run a Kotlin/Wasm project, you need to update the settings of the target environment:

  • For version 109:

    Run the application with the --js-flags=--experimental-wasm-gc command line argument.

  • For version 110 or later:

    1. Go to chrome://flags/#enable-webassembly-garbage-collection in your browser.

    2. Enable WebAssembly Garbage Collection.

    3. Relaunch your browser.

For version 109 or later:

  1. Go to about:config in your browser.

  2. Enable javascript.options.wasm_function_references and javascript.options.wasm_gc options.

  3. Relaunch your browser.

For version 109 or later:

Run the application with the --js-flags=--experimental-wasm-gc command line argument.

Leave your feedback on Kotlin/Wasm

We'd appreciate any feedback you may have!

New JVM incremental compilation by default in Gradle

The new approach to incremental compilation, which has been available since Kotlin 1.7.0, now works by default. You no longer need to specify kotlin.incremental.useClasspathSnapshot=true in your gradle.properties to enable it.

We'd appreciate your feedback on this. You can file an issue in YouTrack.

Update regarding Kotlin/Native targets

The Kotlin team decided to revisit the list of targets supported by Kotlin/Native, split them into tiers, and deprecate some of them starting with Kotlin 1.8.20-RC2. See the Kotlin/Native target support section for the full list of supported and deprecated targets.

There are now 3 tiers of support depending on how well a target is supported and tested in the Kotlin/Native compiler. A target can be moved to a different tier. For example, we'll do our best to provide full support for iosArm64 in the future, as it is important for Kotlin Multiplatform Mobile.

The following targets have been deprecated with Kotlin 1.8.20-RC2 and will be removed in 1.9.20:

  • iosArm32

  • watchosX86

  • wasm32

  • mingwX86

  • linuxArm32Hfp

  • linuxMips32

  • linuxMipsel32

If you're a library author, follow these target tiers to decide which targets should be tested on CI tools and which ones can be skipped. The Kotlin team will use the same approach when developing official Kotlin libraries, like kotlinx.coroutines.

Check out our blog post to learn more about the reasons for these changes.

Preview of Gradle composite builds support in Kotlin Multiplatform

Starting with 1.8.20-RC2, Kotlin Multiplatform supports Gradle composite builds. Composite builds allow you to include builds of separate projects or parts of the same project into a single build.

Due to some technical challenges, using Gradle composite builds with Kotlin Multiplatform was only partially supported. Kotlin 1.8.20-RC2 contains a preview of the improved support that should work with a larger variety of projects. To try it out, add the following option to your gradle.properties:


This option enables a preview of the new import mode. Besides the support for composite builds, it provides a smoother import experience in multiplatform projects, as we've included major bug fixes and improvements to make the import more stable.

Known issues

It's still a preview version that needs further stabilization, and you might encounter some issues with import along the way. Here are some known issues we're planning to fix before the final release of Kotlin 1.8.20:

  • There's no Kotlin 1.8.20 plugin available for IntelliJ IDEA 2023.1 EAP yet. Despite that, you can still set the Kotlin Gradle plugin version to 1.8.20-RC2 and try out composite builds in this IDE.

  • If your projects include builds with a specified rootProject.name, composite builds may fail to resolve the Kotlin metadata. For the workaround and details, see this Youtrack issue.

We encourage you to try it out and submit all reports on YouTrack to help us make it the default in Kotlin 1.9.0.

Improved output for Gradle errors in Xcode

If you had issues building your multiplatform projects in Xcode, you might have encountered a "Command PhaseScriptExecution failed with a nonzero exit code" error. This message signals that the Gradle invocation has failed, but it's not very helpful when trying to detect the problem.

Starting with Kotlin 1.8.20-RC2, Xcode can parse the output from the Kotlin/Native compiler. Furthermore, in case the Gradle build fails, you'll see an additional error message from the root cause exception in Xcode. In most cases, it'll help to identify the root problem.

Improved output for Gradle errors in Xcode

The new behavior is enabled by default for the standard Gradle tasks for Xcode integration, like embedAndSignAppleFrameworkForXcode that can connect the iOS framework from your multiplatform project to the iOS application in Xcode. It can also be enabled (or disabled) with the kotlin.native.useXcodeMessageStyle Gradle property.

Experimental support for AutoCloseable interface in standard library

The AutoCloseable interface has been added to the common standard library so that you can use one common interface for all libraries to close resources. In Kotlin/JVM, the AutoCloseable interface is an alias for java.lang.AutoClosable.

In addition, the extension function use() is now included, which executes a given block function on the selected resource and then closes it down correctly, whether an exception is thrown or not.

There is no public class in the common standard library that implements the AutoCloseable interface. In the example below, we define the XMLWriter interface and assume that there is a resource that implements it. For example, this resource could be a class that opens a file, writes XML content, and then closes it.

interface XMLWriter : AutoCloseable { fun document(encoding: String, version: String, content: XMLWriter.() -> Unit) fun element(name: String, content: XMLWriter.() -> Unit) fun attribute(name: String, value: String) fun text(value: String) } fun writeBooksTo(writer: XMLWriter) { writer.use { xml -> xml.document(encoding = "UTF-8", version = "1.0") { element("bookstore") { element("book") { attribute("category", "fiction") element("title") { text("Harry Potter and the Prisoner of Azkaban") } element("author") { text("J. K. Rowling") } element("year") { text("1999") } element("price") { text("29.99") } } element("book") { attribute("category", "programming") element("title") { text("Kotlin in Action") } element("author") { text("Dmitry Jemerov") } element("author") { text("Svetlana Isakova") } element("year") { text("2017") } element("price") { text("25.19") } } } } } }

Experimental support for Base64 encoding in standard library

We've added support for Base64 encoding and decoding. We provide 3 class instances, each using different encoding schemes and displaying different behaviors. Use the Base64.Default instance for the standard Base64 encoding scheme.

Use the Base64.UrlSafe instance for the “URL and Filename safe” encoding scheme.

Use the Base64.Mime instance for the MIME encoding scheme. When you use the Base64.Mime instance, all encoding functions insert a line separator every 76 characters. In the case of decoding, any illegal characters are skipped and don't throw an exception.

val foBytes = "fo".map { it.code.toByte() }.toByteArray() Base64.Default.encode(foBytes) // "Zm8=" // Alternatively: // Base64.encode(foBytes) val foobarBytes = "foobar".map { it.code.toByte() }.toByteArray() Base64.UrlSafe.encode(foobarBytes) // "Zm9vYmFy" Base64.Default.decode("Zm8=") // foBytes // Alternatively: // Base64.decode(foBytes) Base64.UrlSafe.decode("Zm9vYmFy") // foobarBytes

You can use additional functions to encode or decode bytes into an existing buffer, as well as to append the encoding result to a provided Appendable type object.

In Kotlin/JVM, we've also added the extension functions encodingWith() and decodingWith() to enable you to perform Base64 encoding and decoding with input and output streams.

How to update to Kotlin 1.8.20-RC2

Install Kotlin 1.8.20-RC2 in any of the following ways:

  • If you use the Early Access Preview update channel, the IDE will suggest automatically updating to 1.8.20-RC2 as soon as it becomes available.

  • If you use the Stable update channel, you can change the channel to Early Access Preview at any time by selecting Tools | Kotlin | Configure Kotlin Plugin Updates in your IDE. You'll then be able to install the latest preview release. Check out these instructions for details.

Once you've installed 1.8.20-RC2, don't forget to change the Kotlin version to 1.8.20-RC2 in your build scripts.

Last modified: 27 March 2023