<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Kotlin : A concise multiplatform language developed by JetBrains | The JetBrains Blog</title>
	<atom:link href="https://blog.jetbrains.com/kotlin/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.jetbrains.com</link>
	<description>Developer Tools for Professionals and Teams</description>
	<lastBuildDate>Thu, 01 Oct 2026 08:57:43 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://blog.jetbrains.com/wp-content/uploads/2026/09/icon-512.webp</url>
	<title>Kotlin : A concise multiplatform language developed by JetBrains | The JetBrains Blog</title>
	<link>https://blog.jetbrains.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>The Companions to Come</title>
		<link>https://blog.jetbrains.com/kotlin/2026/09/the-companions-to-come/</link>
		
		<dc:creator><![CDATA[Alejandro Serrano Mena]]></dc:creator>
		<pubDate>Wed, 30 Sep 2026 10:33:03 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/KT-social-BlogFeatured-1280x720-1-2.png</featuredImage>		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[news]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=743559</guid>

					<description><![CDATA[We are working on extensions to our companions mechanism to unlock new code patterns and improve interoperability across different platforms. This post outlines these new features and provides preliminary guidance on migration. Companion blocks and extensions Many programming languages provide a notion of class or type members – functionality that does not belong to each [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>We are working on extensions to our companions mechanism to unlock new code patterns and improve interoperability across different platforms. This post outlines these new features and provides preliminary guidance on migration.</p>



<h2 class="wp-block-heading">Companion blocks and extensions</h2>



<p>Many programming languages provide a notion of class or type members – functionality that does not belong to each particular value of a class, but to the class itself. Constants, utilities, and factory methods are often in this group.<br></p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">val v1 = Vector(1.0, 2.0)             // a regular vector
val v2 = Vector.ZERO                  // the constant zero vector
val v3 = Vector.unit(angle = PI / 2)  // unit vector with an angle </pre>



<p>Previously, <a href="https://kotlinlang.org/docs/object-declarations.html#companion-objects" target="_blank" rel="noopener">companion objects</a> were used to define these members. From Kotlin 2.5.0 on, you can also use an experimental companion block, which is very close syntactically, but with profound changes in compilation.<br></p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">data class Vector(val x: Double, val y: Double) {
  companion {
    val ZERO = Vector(0.0, 0.0)
  }
}</pre>



<p>In fact, these members may not be defined directly on the class itself. You can also use an experimental companion extension to declare new class members in a type, even if you don&#8217;t control them.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">companion fun Vector.unit(angle: Double) = Vector(cos(angle), sin(angle))</pre>



<p>The design of companion blocks and extensions overcomes the limitations imposed by companion objects. First of all, you can define companion extensions for any class or interface – whether you control it or not, whether it originally comes from Kotlin or from Java, or whether it has a companion object or not.&nbsp;<br><br>Second, the compilation strategy resembles that of static members in other platforms. For example, on the JVM, companion blocks are compiled as static members. This has additional implications for Kotlin Multiplatform: you can now define expected companion block members and actualize them using a Java class that contains static members.</p>



<p><em>If you want to know more about this upcoming language feature, the corresponding </em><a href="https://github.com/Kotlin/KEEP/blob/main/proposals/KEEP-0449-companions-block-extension.md" target="_blank" rel="noopener"><em>KEEP proposal</em></a><em> contains all the information.</em></p>



<h2 class="wp-block-heading">Using experimental companions</h2>



<p>Companion blocks and extensions are experimental features <strong>available starting Kotlin 2.5.0-Beta1</strong>. That means that you need to pass an additional compiler flag to use the feature:</p>



<ul class="wp-block-list">
<li><code>-Xcompanion-blocks</code> to allow companion blocks.</li>



<li><code>-Xcompanion-blocks-and-extensions</code> to allow both companion blocks and extensions.<br></li>
</ul>



<p>Using the second feature causes the compiler to produce pre-release binaries, which means libraries using companion extensions may not be consumed as dependencies until the feature becomes stable. This restriction does not apply to exposing companion blocks, although consumers of such blocks still need to enable the companion blocks feature.</p>



<h2 class="wp-block-heading">What about my companion objects?&nbsp;</h2>



<p>This leads to a natural question: What is the role of companion objects in a language with companion blocks and extensions? There are two answers to this question:</p>



<ul class="wp-block-list">
<li>On the one hand, most usages of companion objects would be better served by companion blocks, so new code may prefer the latter to the former.</li>



<li>On the other hand, there are a few use cases that are only served by companion objects. For example, if your companion needs to implement a particular interface, companion objects are the only possibility, since they compile to a full-fledged class.<br></li>
</ul>



<p>There&#8217;s no need to migrate, though. Companion objects are an integral part of Kotlin, and support for them is fully guaranteed.&nbsp;</p>



<p>If you prefer to move to companion blocks, removing the <code>object</code> keyword should be enough in most cases – but note that the project and any code depending on it need to be recompiled. Other tooling in the ecosystem may not be ready for companion blocks, although we’re trying to ensure major players provide this support as soon as possible.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>The State of Kotlin in 2026 Report</title>
		<link>https://blog.jetbrains.com/kotlin/2026/09/state-of-kotlin-2026-report/</link>
		
		<dc:creator><![CDATA[Daria Voronina]]></dc:creator>
		<pubDate>Tue, 29 Sep 2026 12:38:29 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/X-800x418-1.png</featuredImage>		<category><![CDATA[news]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[backend]]></category>
		<category><![CDATA[kotlin-multiplatform]]></category>
		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[state-of-kotlin]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=743045</guid>

					<description><![CDATA[In 2026, Kotlin turned fifteen. Over those fifteen years, Kotlin has built a mature ecosystem, been adopted by companies around the world, and established a large and active developer community. Fifteen years is long enough to understand which technology trends lasted and which didn’t. This report looks back at Kotlin’s first fifteen years to see [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>In 2026, Kotlin turned fifteen. Over those fifteen years, Kotlin has built a mature ecosystem, been adopted by companies around the world, and established a large and active developer community.</p>



<p>Fifteen years is long enough to understand which technology trends lasted and which didn’t. This report looks back at Kotlin’s first fifteen years to see what they reveal about how the language matured, while answering questions like: “Is Kotlin here to stay?”, “Can Kotlin scale across platforms?”, and “How does Kotlin fit into the AI era?”</p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotlinlang.org/assets/state-of-kotlin-2026.pdf?utm_source=blog&#038;utm_medium=referral&#038;utm_campaign=state-of-kotlin-26" target="_blank" rel="noopener"><i class="download-icon"></i>View Report</a></p>



<div data-wp-interactive="core/file" class="wp-block-file"><object data-wp-bind--hidden="!state.hasPdfPreview" hidden class="wp-block-file__embed" data="https://blog.jetbrains.com/wp-content/uploads/2026/09/state-of-kotlin-2026-compressed.pdf" type="application/pdf" style="width:100%;height:600px" aria-label="Embed of State of Kotlin in 2026."></object><a id="wp-block-file--media-a30706cf-a57b-4267-8f5d-16c8d75da8fe" href="https://blog.jetbrains.com/wp-content/uploads/2026/09/state-of-kotlin-2026-compressed.pdf" target="_blank" rel="noreferrer noopener">State of Kotlin in 2026</a></div>



<p>Today, developers worldwide use Kotlin across a diverse range of applications, including mobile, backend, and multiplatform. The language is also finding its place in the rapidly evolving AI space, where Kotlin’s strengths, like static typing, null safety, and coroutines, take on new relevance. Kotlin is actively participating in the shift toward AI-assisted development: Among surveyed Kotlin developers, 93% use at least one AI coding tool, while 81% already use or are likely to try AI coding agents. An equal share – 81% – say that AI-generated Kotlin code is fully correct or requires only minor fixes.</p>



<p>The <em>State of Kotlin in 2026</em> report combines data from JetBrains research with independent industry data and real-world adoption evidence. Some findings confirmed what we expected; others challenged some familiar assumptions. While the language remains deeply established in Android development, more than half of Kotlin developers now report working on backend projects, highlighting how far its usage has expanded beyond mobile.</p>



<p>Together, these findings point to a broader story: Kotlin’s evolution isn’t just about growth, but about how diverse its usage has become, spanning backend, multiplatform, AI-assisted development, and more. At the same time, the developer community itself has grown more experienced.</p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotlinlang.org/state-of-kotlin-2026/?utm_source=blog&#038;utm_medium=button&#038;utm_campaign=state-of-kotlin-26" target="_blank" rel="noopener"><i class="download-icon"></i>State of Kotlin in 2026: Explore the highlights</a></p>



<p>See what the data tells us about how Kotlin has evolved and where its ecosystem stands today.</p>



<p>Read the full report → <a href="https://kotlinlang.org/assets/state-of-kotlin-2026.pdf?utm_source=blog&amp;utm_medium=referral&amp;utm_campaign=state-of-kotlin-26" data-type="link" data-id="https://kotlinlang.org/assets/state-of-kotlin-2026.pdf?utm_source=blog&amp;utm_medium=referral&amp;utm_campaign=state-of-kotlin-26" target="_blank" rel="noreferrer noopener">Download the State of Kotlin in 2026 PDF</a></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>A More Reliable Compilation Scheme for Kotlin Multiplatform Modules</title>
		<link>https://blog.jetbrains.com/kotlin/2026/09/a-more-reliable-compilation-scheme-for-kotlin-multiplatform-modules/</link>
		
		<dc:creator><![CDATA[Aleksey Zamulla]]></dc:creator>
		<pubDate>Mon, 28 Sep 2026 09:38:26 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/KM-social-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[compiler]]></category>
		<category><![CDATA[experimental-features]]></category>
		<category><![CDATA[kotlin-multiplatform]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=742576</guid>

					<description><![CDATA[The current compilation approach to Kotlin Multiplatform projects works, but sometimes can lead to unexpected or hard-to-predict behavior. For example: With Kotlin 2.5.0-Beta1, we introduced an optional &#8220;separate compilation&#8221; approach to KMP that solves both problems: make the compilation results consistent with IDE analysis, and point more consistently to problematic calls of library code from [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The current compilation approach to Kotlin Multiplatform projects works, but sometimes can lead to unexpected or hard-to-predict behavior. For example:</p>



<ul class="wp-block-list">
<li>The IDE analysis disagrees with the compiler on an overload, type inference, or whether the code should compile at all – with the IDE being <strong>stricter</strong> than the compiler.</li>



<li>Your <code>commonTest</code> code can unexpectedly call something from a platform source set, breaking your assumptions.</li>
</ul>



<p>With Kotlin 2.5.0-Beta1, we introduced an optional &#8220;separate compilation&#8221; approach to KMP that solves both problems: make the compilation results consistent with IDE analysis, and point more consistently to problematic calls of library code from common source sets. As a bonus, this approach enables us to implement <a href="https://kotlinlang.org/docs/gradle-compilation-and-caches.html#incremental-compilation" target="_blank" rel="noopener">incremental compilation</a> for common source sets.</p>



<p>The separate compilation feature is <a href="https://kotlinlang.org/docs/components-stability.html#stability-levels-explained" target="_blank" rel="noopener">Experimental</a> and disabled by default. To opt in, add the following compiler option to your <code>gradle.properties</code> file (note the <a href="#known-issues">known issues</a>):</p>



<pre class="EnlighterJSRAW">kotlin.kmp.separateCompilation=true</pre>



<p>Let&#8217;s look closer at the problem and the solution.</p>



<h2 class="wp-block-heading">How multiplatform declarations are resolved within a module</h2>



<p>Within a module, multiplatform code performs predictably:</p>



<pre class="EnlighterJSRAW">// jvmMain
fun foo() {}

// commonMain
fun test() {
    foo() // Unresolved reference in IDE and during compilation
}</pre>



<p>The compiler and the IDE agree: The code in <code>commonMain</code> is also compiled to other platforms, for example, to Kotlin/JS, and there might not be a <code>fun foo()</code> declaration in <code>jsMain</code>. <a href="https://kotlinlang.org/docs/multiplatform/multiplatform-expect-actual.html" target="_blank" rel="noopener">Expect/actual declarations</a> exist precisely to solve this problem: explicitly tie platform-specific declarations to common ones.</p>



<p>You would expect that the reference is also flagged as unresolved when the <code>foo()</code> function is declared in a dependency (a module in the same project or a binary artifact like Kotlin standard library or <code>kotlinx-coroutines</code>). Unfortunately, with the current compilation scheme that&#8217;s where the IDE and the compiler disagree.</p>



<h2 class="wp-block-heading">How multiplatform declarations are resolved between modules</h2>



<p>To understand where the problems stem from, let&#8217;s look closer at the current compilation setup.</p>



<h3 class="wp-block-heading">Kotlin Multiplatform compilation setup</h3>



<p>In a KMP project, a module with common code usually consists of several source sets: in the example above it&#8217;s a shared source set (<code>commonMain</code>) and a platform source set for a declared target (<code>jvmMain</code> for Kotlin/JVM).</p>



<p>With that setup, the compiler can produce the following artifacts:</p>



<ul class="wp-block-list">
<li>A platform artifact for each platform source set like <code>jvmMain</code> – <code>*.jar</code> on JVM, <code>*.klib</code> on other platforms.</li>



<li>A metadata KLIB for each common or intermediate source set (like <code>commonMain</code> or <code>nativeMain</code>). A metadata KLIB contains all declarations from the compiled source set without bodies.</li>
</ul>



<p>So where do the problems start?</p>



<h3 class="wp-block-heading">Common code is compiled against platform artifacts; IDE disagrees</h3>



<p>During compilation of a platform source set, both the code inside it (<code>jvmMain</code>) <strong>and</strong> the code in all relevant shared source sets (<code>commonMain</code> and other <a href="https://kotlinlang.org/docs/multiplatform/multiplatform-hierarchy.html#default-hierarchy-template" target="_blank" rel="noopener">intermediate source sets</a>) is compiled against the platform artifacts of its dependencies. Here code from <code>commonMain</code> has a chance to implicitly resolve to a <code>jvmMain</code> declaration.</p>



<p>If you expect this to happen, you&#8217;re probably fine. It would be more transparent and predictable, however, if <code>commonMain</code> could only call declarations from the dependency&#8217;s <code>commonMain</code> (as listed in the dependency&#8217;s metadata KLIB).</p>



<p>This is exactly what the code analysis in IntelliJ IDEA already assumes. As <code>jvmMain</code> declarations are not included in the KLIB metadata, IntelliJ IDEA reports the unresolved reference error when <code>commonMain</code> refers to something not declared in common code explicitly:</p>



<pre class="EnlighterJSRAW">// lib/jvmMain
class Foo

// app/commonMain
fun main() {
    Foo() // Unresolved reference in the IDE, no error during compilation
}</pre>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" fetchpriority="high" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Current-compilation-with-IDEA-1.jpg" alt="" class="wp-image-742856"/></figure>



<p>The same mechanism is also in play with <code>commonTest</code> source sets, because tests also &#8220;depend&#8221; on main code: <code>commonTest</code> compiled against <code>jvmMain</code> can successfully call a declaration from platform code, instead of being restricted to declarations in <code>commonMain</code>. IDE reports the same unresolved reference problem:</p>



<pre class="EnlighterJSRAW">// app/jvmMain
class Foo

// app/commonTest
fun main() {
    Foo() // &quot;Unresolved reference&quot; in the IDE, no error during compilation
}</pre>



<p>Let&#8217;s see how separate compilation solves these problems.</p>



<h2 class="wp-block-heading">How separate compilation solves the problem</h2>



<p>KMP separate compilation makes the compiler behave stricter (aligning with the IDE expectation) when compiling common source sets of KMP projects. This makes the overall experience more predictable, although you may need to adjust your old code for stricter compile-time checks.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Separate-compilation-1.jpg" alt="" class="wp-image-742867"/></figure>



<p>Let&#8217;s look at specific code examples and what happens to them with the switch between compilation schemes.</p>



<h3 class="wp-block-heading">Red code in IDE, no error during compilation</h3>



<p>When you turn on separate compilation, this code stops compiling, because compiler now resolves common code calls strictly using metadata KLIB declarations:</p>



<pre class="EnlighterJSRAW">// lib/jvmMain
class Foo

// app/commonMain
fun main() {
    Foo() // Unresolved reference in IDE, now also a compilation error
}</pre>



<p>The fix is to show an explicit connection: declare an <code>expect class</code> in <code>lib/commonMain</code> and make the platform <code>Foo</code> class an <code>actual class</code>:</p>



<pre class="EnlighterJSRAW">// lib/commonMain
expect class Foo()

// lib/jvmMain
actual class Foo

// app/commonMain
fun main() {
    Foo() // ok
}</pre>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Fixed-version-if-your-code-is-broken-by-separate-compilation.jpg" alt="" class="wp-image-742878"/></figure>



<p>Same for <code>commonTest</code>: with separate compilation, the test code won&#8217;t resolve to a platform call in <code>jvmMain</code>. If that&#8217;s what you want to test, declare the corresponding <code>expect</code> in <code>commonMain</code>:</p>



<pre class="EnlighterJSRAW">// app/jvmMain
actual class Foo

// app/commonMain
expect class Foo

// app/commonTest
fun main() {
    Foo() // Ok, calls Foo from jvmMain
}</pre>



<h3 class="wp-block-heading">IDE and compiler don&#8217;t agree on selected overload</h3>



<p>When several overloads are declared in <code>lib/commonMain</code> and <code>lib/jvmMain</code>, the IDE currently interprets the call from <code>app/commonMain</code> differently from the compiler:</p>



<pre class="EnlighterJSRAW">// lib/commonMain
fun foo(x: Any) = &quot;common&quot;

// lib/jvmMain
fun foo(x: String) = &quot;platform&quot;

// app/commonMain
fun main() {
    // &quot;Go to declaration&quot; on foo() jumps to lib/commonMain,
    // but at runtime &quot;platform&quot; is printed
    println(foo(&quot;&quot;))
}</pre>



<p>The IDE resolves the <code>foo("")</code> call to the declaration <code>fun foo(x: Any)</code> in <code>lib/commonMain</code>, as it assumes that common code can only depend on common declarations. But during the actual compilation <code>app/commonMain</code> currently sees both declarations and chooses the more specific overload <code>fun foo(x: String)</code>. At runtime, &#8220;platform&#8221; is printed.</p>



<p>With the new compilation scheme, the call is resolved to <code>fun foo(x: Any)</code> in <code>lib/commonMain</code> and at runtime, and &#8220;common&#8221; is printed.</p>



<h3 class="wp-block-heading">Unexpected type inference</h3>



<p>A trickier problem can occur when the error is triggered not at the <code>app/commonMain</code> call site, but in platform code. In the following example the IDE actually sees no problem, but the JVM compilation fails.</p>



<p><code>actual</code> classes are allowed to have different supertypes than their <code>expect</code> counterparts, so you can reasonably arrive at the following code structure:</p>



<pre class="EnlighterJSRAW">// eventsLib/commonMain
interface Event { val name: String }

expect class ClickEvent(target: String) : Event { override val name: String }
expect class ScrollEvent(offset: Int) : Event { override val name: String }

// eventsLib/jvmMain — serialized events get queued or stored in a session
actual class ClickEvent actual constructor(target: String) : Event, Serializable { /* ... */ }
actual class ScrollEvent actual constructor(offset: Int) : Event, Serializable { /* ... */ }

// app/commonMain
fun currentEvent() = if (clicked()) ClickEvent(&quot;buy&quot;) else ScrollEvent(120)

fun report() = currentEvent().name // e: Unresolved reference &#039;name&#039; only on the JVM</pre>



<p>The IDE only matches <code>commonMain</code> declarations, which allows it to (correctly) infer the return type of <code>currentEvent()</code> as <code>Event</code> and resolve the <code>.name</code> reference.</p>



<p>On JVM, however, the library declares an additional supertype for each <code>actual</code> class. When compiling <code>app</code> for the JVM, the compiler currently resolves common code against the <code>eventsLib</code> JAR which has the <code>eventsLib/jvmMain</code> version of the classes. With the two supertypes, the return type inference for the <code>currentEvent()</code> call arrives at <code>Any</code>, which doesn&#8217;t have a <code>.name</code>, and the JVM compilation fails.</p>



<p>With the separate compilation enabled, <code>app/commonMain</code> code is resolved only against <code>eventsLib/commonMain</code> declarations. So when compiling the JVM target of <code>app</code>, the compiler already has the resolved common code and has inferred the <code>Event</code> return type for the <code>currentEvent()</code> function. The JVM compilation runs separately, doesn&#8217;t have to infer anything, and finishes successfully.</p>



<h2 class="wp-block-heading">How to enable separate compilation</h2>



<p>The separate compilation feature is <a href="https://kotlinlang.org/docs/components-stability.html#stability-levels-explained" target="_blank" rel="noopener">Experimental</a> and disabled by default. To opt in, add the following compiler option to your <code>gradle.properties</code> file (note the known issues below):</p>



<pre class="EnlighterJSRAW">kotlin.kmp.separateCompilation=true</pre>



<h2 class="wp-block-heading" id="known-issues">Known issues</h2>



<p>For separate compilation to work correctly in KMP projects, it is important that authors of multiplatform libraries publish the metadata KLIBs. This is the default behavior for publishing tasks of the KMP Gradle plugin, but the new compilation scheme makes metadata KLIBs essential.</p>



<p>There are some known issues with KMP separate compilation that are still being fixed:</p>



<ul class="wp-block-list">
<li>Some problems with commonization of cinterops (like <a href="https://youtrack.jetbrains.com/issue/KT-88178" target="_blank" rel="noopener">KT-88178</a> or <a href="https://youtrack.jetbrains.com/issue/KT-41509" target="_blank" rel="noopener">KT-41509</a>). These are unlikely to affect an average KMP project, but enable the separate compilation mode with caution if you use <a href="https://kotlinlang.org/docs/native-c-interop.html" target="_blank" rel="noopener">C interoperability</a>.</li>



<li>KMP modules with common source sets and a single declared target are <strong>not</strong> affected by separate compilation for now.</li>



<li>Various smaller issues such as <a href="https://youtrack.jetbrains.com/issue/KT-88148" target="_blank" rel="noopener">KT-88148</a>.</li>
</ul>



<h2 class="wp-block-heading">Send feedback</h2>



<p>We&#8217;d be grateful for any feedback you have on separate compilation: leave a comment in the <a href="https://youtrack.jetbrains.com/issue/KT-89725" target="_blank" rel="noopener">dedicated YouTrack issue</a>.</p>
]]></content:encoded>
					
		
		
		                    <language>
                        <code><![CDATA[zh-hans]]></code>
                        <url>https://blog.jetbrains.com/zh-hans/kotlin/2026/09/a-more-reliable-compilation-scheme-for-kotlin-multiplatform-modules/</url>
                    </language>
                	</item>
		<item>
		<title>Kotlin 2.4.20 Released</title>
		<link>https://blog.jetbrains.com/kotlin/2026/09/kotlin-2-4-20-released/</link>
		
		<dc:creator><![CDATA[Daniel Csorba]]></dc:creator>
		<pubDate>Mon, 07 Sep 2026 11:30:57 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/KT-releases-BlogSocialShare-1280x720-1.png</featuredImage>		<category><![CDATA[releases]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=737362</guid>

					<description><![CDATA[The Kotlin 2.4.20 release is out! Here are the main highlights: For the complete list of changes, see What&#8217;s new in Kotlin 2.4.20 or the release notes on GitHub. How to install Kotlin 2.4.20 The latest version of Kotlin is included in the latest versions of IntelliJ IDEA and Android Studio. To update to the [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>The Kotlin 2.4.20 release is out! Here are the main highlights:</p>



<ul class="wp-block-list">
<li><strong>Standard library</strong>: Support for coroutine stack trace recovery, new functions for checking equality and uniqueness of collection elements, and new overloads for <code>kotlin.test</code> assertion functions.</li>



<li><strong>Kotlin/Native</strong>: New Swift export features, improved incremental compilation, and automatically generated <code>Package.swift</code> files for SwiftPM dependencies.</li>



<li><strong>Kotlin/Wasm</strong>:<strong> </strong>Changes to top-level <code>require()</code> calls in <code>@JsFun</code> declarations, improved companion object initialization order, and support for Wasmtime in the Kotlin Gradle plugin.</li>



<li><strong>Kotlin/JS</strong>: A new DSL for browser testing, support for exporting suspend lambdas as async functions, and improved exportability of data classes.</li>



<li><strong>Gradle</strong>: Support for Gradle 9.7.0 and improved reporting in the Problems API.</li>



<li><strong>Build tools API</strong>: Support for new targets: Kotlin/JS, Kotlin/Wasm, and Kotlin metadata.</li>



<li><strong>Kotlin compiler</strong>: The `kotlinr` runner command and a separate native image.</li>
</ul>



<p></p>



<p>For the complete list of changes, see <a href="https://kotlinlang.org/docs/whatsnew2420.html" target="_blank" rel="noopener">What&#8217;s new in Kotlin 2.4.20</a> or the <a href="https://github.com/JetBrains/kotlin/releases/tag/v2.4.20" target="_blank" rel="noopener">release notes on GitHub</a>.</p>



<figure class="wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio"><div class="wp-block-embed__wrapper">
<iframe loading="lazy" title="What&#039;s New in Kotlin 2.4.20" src="https://www.youtube.com/embed/UhRfN7fx5rs?feature=oembed" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe>
</div></figure>



<h2 class="wp-block-heading">How to install Kotlin 2.4.20</h2>



<p>The latest version of Kotlin is included in the latest versions of <a href="https://www.jetbrains.com/idea/download/" target="_blank" rel="noopener">IntelliJ IDEA</a> and <a href="https://developer.android.com/studio" target="_blank" rel="noopener">Android Studio</a>.</p>



<p>To update to the new Kotlin version, make sure your IDE is updated to the latest version and <a href="https://kotlinlang.org/docs/releases.html#update-to-a-new-kotlin-version" target="_blank" rel="noopener">change the Kotlin version</a> to 2.4.20 in your build scripts.</p>



<p>If you need the command-line compiler, download it from the <a href="https://github.com/JetBrains/kotlin/releases/tag/v2.4.20" target="_blank" rel="noopener">GitHub release page</a>.</p>



<p><strong>If you run into any problems:</strong></p>



<ul class="wp-block-list">
<li>Find help on <a href="https://app.slack.com/client/T09229ZC6" target="_blank" rel="noopener">Slack</a> (<a href="https://surveys.jetbrains.com/s3/kotlin-slack-sign-up" target="_blank" rel="noopener">get an invite</a>).</li>



<li>Report issues to our issue tracker, <a href="https://youtrack.jetbrains.com/issues/KT" target="_blank" rel="noopener">YouTrack</a>.</li>
</ul>



<div style="background-color: #f1f6fe; margin-bottom: 2px; padding: 5px; margin-right: 0%; text-align: left; min-height: px;">
<p>Stay up to date with the latest Kotlin features! Subscribe to receive Kotlin updates by filling out the form at the bottom of this post. ⬇️</p>
</div>



<h2 class="wp-block-heading">Special thanks to our EAP Champions</h2>



<ul class="wp-block-list">
<li><a href="https://bsky.app/profile/zacsweers.dev" target="_blank" rel="noopener">Zac Sweers</a></li>



<li><a href="https://x.com/noraltavir">Alexander Nozik</a></li>



<li><a href="https://github.com/BoD" target="_blank" rel="noopener">Benoit Lubek</a></li>



<li><a href="https://github.com/ychescale9" target="_blank" rel="noopener">Yang</a></li>



<li><a href="https://github.com/rickclephas" target="_blank" rel="noopener">Rick Clephas</a></li>



<li><a href="https://www.linkedin.com/in/johannessvensson/" target="_blank" rel="noopener">Johannes Svensson</a></li>



<li><a href="https://www.linkedin.com/in/lukasz-wasylkowski/" target="_blank" rel="noopener">Łukasz Wasylkowski</a></li>



<li><a href="https://sterlingalbury.com/" target="_blank" rel="noopener">Sterling Albury</a></li>



<li><a href="https://github.com/HagamosVideojuegos" target="_blank" rel="noopener">David Lopez</a></li>



<li><a href="https://github.com/molikuner" target="_blank" rel="noopener">Florian Schreiber</a></li>



<li><a href="https://github.com/msotho" target="_blank" rel="noopener">Sechaba Mofokeng</a></li>



<li><a href="https://github.com/JesusMcCloud" target="_blank" rel="noopener">Bernd Prünster</a></li>



<li><a href="https://x.com/andy_lamax">Anderson Lameck</a></li>



<li><a href="https://github.com/dayanruben" target="_blank" rel="noopener">Dayan Ruben</a></li>



<li><a href="https://kotlinlang.slack.com/team/U03PLFM837A" target="_blank" rel="noopener">Josh Stagg</a></li>



<li><a href="https://www.linkedin.com/in/yuri-geronimus/" target="_blank" rel="noopener">Yuri Geronimus</a></li>



<li><a href="https://github.com/seregamorph" target="_blank" rel="noopener">Sergey Chernov</a></li>



<li><a href="https://ivan.canet.dev/" target="_blank" rel="noopener">Ivan Canet</a></li>



<li><a href="https://github.com/Zordid" target="_blank" rel="noopener">Olaf Gottschalk</a></li>



<li><a href="https://github.com/MohamedRejeb" target="_blank" rel="noopener">Mohamed Rejeb</a></li>
</ul>



<h1 class="wp-block-heading">Further reading</h1>



<ul class="wp-block-list">
<li><a href="https://kotlinlang.org/docs/whatsnew2420.html" target="_blank" rel="noopener">What’s new in Kotlin 2.4.20 documentation</a></li>



<li><a href="https://kotlinlang.org/docs/compatibility-guide-24.html" target="_blank" rel="noopener">Kotlin 2.4 compatibility guide</a></li>



<li><a href="https://blog.jetbrains.com/kotlin/2022/11/eap-champions/">Kotlin EAP Champions</a></li>
</ul>



<p></p>
]]></content:encoded>
					
		
		
		                    <language>
                        <code><![CDATA[zh-hans]]></code>
                        <url>https://blog.jetbrains.com/zh-hans/kotlin/2026/09/kotlin-2-4-20-released/</url>
                    </language>
                	</item>
		<item>
		<title>Kotlin Toolchain 0.12: Multiplatform Library Publishing, Wasm Apps, and More</title>
		<link>https://blog.jetbrains.com/kotlin/2026/09/kotlin-toolchain-0-12-multiplatform-library-publishing-wasm-apps-and-more/</link>
		
		<dc:creator><![CDATA[Joffrey Bion]]></dc:creator>
		<pubDate>Thu, 03 Sep 2026 10:40:05 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/09/KT-social-BlogFeatured-1280x720-1.png</featuredImage>		<product ><![CDATA[amper]]></product>
		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[releases]]></category>
		<category><![CDATA[toolchain]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[toolchains]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=736282</guid>

					<description><![CDATA[Kotlin Toolchain 0.12.0 is out. This release brings some long-awaited features: multiplatform libraries publication, a preview of Wasm application support, Compose Hot Reload from the command line, and more.&#160; Read on for the details, and check the release notes for the full list of changes and bug fixes. Additionally, klibs.io now uses the Kotlin Toolchain [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Kotlin Toolchain 0.12.0 is out. This release brings some long-awaited features: multiplatform libraries publication, a preview of Wasm application support, Compose Hot Reload from the command line, and more.&nbsp;</p>



<p>Read on for the details, and check the <a href="https://github.com/JetBrains/kotlin-toolchain/releases/tag/v0.12.0" target="_blank" rel="noopener">release notes</a> for the full list of changes and bug fixes.</p>



<p>Additionally, <a href="http://klibs.io" target="_blank" rel="noopener">klibs.io</a> now uses the Kotlin Toolchain in production. A real backend and not a sample, it’s built on JDK 21, Spring Boot 4 (with Spring AI), PostgreSQL, and OpenSearch. We’ve converted nine convention plugins to Kotlin Toolchain templates, and two Gradle plugins with no built-in equivalent: Jib and Git Properties, which we’ve implemented as local Kotlin Toolchain plugins. Check out the <a href="https://github.com/JetBrains/klibs-io" target="_blank" rel="noopener">sources</a> yourself.</p>



<p><em>To get support for Kotlin Toolchain’s latest features, use </em><a href="https://www.jetbrains.com/idea/" target="_blank" rel="noopener"><em>IntelliJ IDEA 2026.2.1</em></a><em> (or newer). Make sure the latest version of the </em><a href="https://plugins.jetbrains.com/plugin/31850-kotlin-toolchain" target="_blank" rel="noopener"><em>Kotlin Toolchain plugin</em></a><em> is installed.&nbsp;</em></p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotl.in/zbd4nw" target="_blank" rel="noopener"><i class="download-icon"></i>Try the Kotlin Toolchain</a></p>



<h2 class="wp-block-heading">Kotlin Multiplatform libraries publication</h2>



<p>Library publishing arrived in preview in 0.11, but only for JVM libraries. Starting with 0.12, multiplatform libraries work too, with exactly the same configuration:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="generic" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">product:
  type: lib
  platforms: [jvm, android, iosArm64, iosSimulatorArm64, wasmJs]

settings:
  publishing:
    enabled: true
    group: org.example
    version: 1.0.0</pre>



<p>The Kotlin Toolchain publishes everything your users need to depend on your library from any of its targets: the common API, one artifact per platform, the sources, and the module publication metadata that lets build tools pick the right pieces automatically.</p>



<p><br>Cinterop bindings are supported as well. They are published both commonized and per platform, so your users get the same C API you compiled against without setting up interop themselves. The result is consumable from Gradle projects like any other multiplatform library.<br></p>



<p>For more details, see the <a href="https://kotlin-toolchain.org/latest/user-guide/publishing/" target="_blank" rel="noopener">documentation</a>.</p>



<p>Note: Resources of Compose Multiplatform libraries are not part of the publication yet. Follow <a href="https://youtrack.jetbrains.com/issue/KTC-5698/Support-publication-of-composeResources-as-a-part-of-KMP-library-publication" target="_blank" rel="noopener">KTC-5698</a> for progress.</p>



<h3 class="wp-block-heading">Better compliance with Maven Central quotas</h3>



<p>Because of the new quotas on Maven Central publications that <a href="https://central.sonatype.org/publish/maven-central-publishing-limits/" target="_blank" rel="noopener">Sonatype will soon enforce</a>, we made a few notable changes to reduce the number of files published by default:</p>



<ul class="wp-block-list">
<li>Checksums of signature files (<code>.asc.sha1</code>) are not necessary and are no longer published.</li>



<li>Only the <code>.md5</code> and <code>.sha1</code> checksums are published by default now. If you need to continue publishing the <code>.sha256</code> and <code>.sha512</code> checksums, use <code>settings.publishing.checksums: [md5, sha1, sha256, sha512]</code>.</li>
</ul>



<h2 class="wp-block-heading">Wasm application support</h2>



<p><code>wasm-js/app</code> modules can now be built into a ready-to-use web application.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Wasm-app.png" alt="" class="wp-image-736383" /></figure>



<p>Among the supported features are:</p>



<ul class="wp-block-list">
<li>Running Wasm apps with the <code>kotlin run</code> command.</li>



<li>Customizing <code>index.html</code> and other resources.&nbsp;</li>



<li>Fetching transitive npm dependencies from Kotlin Multiplatform libraries.</li>
</ul>



<p>More information on working with Wasm web applications is available in <a href="https://kotlin-toolchain.org/dev/user-guide/product-types/wasm-js-app/" target="_blank" rel="noopener">the documentation</a>.</p>



<h2 class="wp-block-heading">Terminal UI improvements</h2>



<p>We are actively working to make the output of the <code>kotlin</code> command less verbose and more user-friendly.&nbsp;</p>



<h3 class="wp-block-heading">Diagnostics</h3>



<p>For example, here are some of the recent diagnostics improvements:</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Diagnostics-before-and-after-2.png" alt="" class="wp-image-736410" /></figure>



<h3 class="wp-block-heading">Tests in the status widget</h3>



<p>Running tests are now visible in the status widget under the respective tasks and their suites. There are also short test execution statistics visible during the run.</p>



<figure class="wp-block-video"><video autoplay controls loop muted src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Running-tests.mov"></video></figure>



<p>There are more things to iron out, but we’ll get there.</p>



<h2 class="wp-block-heading">IDE improvements</h2>



<h3 class="wp-block-heading">Compose preview support</h3>



<p>Android modules and <code>kmp/lib</code> modules that have Android as one of their targets now support the Compose preview feature, powered by the <code>androidx.compose.ui.tooling.preview.Preview</code> annotation and the Android plugin.<br></p>



<figure class="wp-block-video"><video autoplay controls loop muted src="https://blog.jetbrains.com/wp-content/uploads/2026/09/KTC-Android-Compose-Preview.mov"></video></figure>



<h3 class="wp-block-heading">Better support for Compose resources</h3>



<p>The IDE now correctly recognizes Compose resources, updates <code>Res</code> classes on the fly, provides navigation, completion, and refactorings that update both XMLs and your code.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Compose-Resources.png" alt="" class="wp-image-736443" /></figure>



<h3 class="wp-block-heading">Android tooling improvements</h3>



<p>Adding to the Compose preview support mentioned above, we have also brought support for more of the Android features you are accustomed to, such as:</p>



<ul class="wp-block-list">
<li>Android Lint&nbsp;</li>



<li>Live Edit</li>



<li>Layout Inspector</li>



<li>Resources (<code>R</code> class) navigation and completion</li>
</ul>



<h3 class="wp-block-heading">iOS improvements</h3>



<p>Starting with IntelliJ IDEA 2026.2.1, the experience of working with iOS applications should be closer to what you’re used to in Gradle projects.</p>



<p>The run configuration now lets you pick a device, configure Xcode options, and choose a debug/release configuration mode.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Xcode-configuration.png" alt="" class="wp-image-736454" /></figure>



<p>We’ve also fixed a few issues with Kotlin/Swift interoperability, which should be more stable now.</p>



<h3 class="wp-block-heading">Inlay hints with coordinates of catalog dependencies</h3>



<p>Catalog dependencies in module files and templates now have an inlay hint next to them displaying coordinates that each entry points to.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/Catalog-inlays.png" alt="" class="wp-image-736476" /></figure>



<h2 class="wp-block-heading">Better Compose Hot Reload support</h2>



<p>We now properly support Compose Hot Reload <strong>from the command line</strong> using the <code>kotlin run --compose-hot-reload-mode</code> command.</p>



<h3 class="wp-block-heading">General improvements</h3>



<ul class="wp-block-list">
<li>The very first reload is now much faster and the build should consume fewer resources.</li>



<li>The <em>Restart the application</em> action from the <em>DevTools</em> menu is now supported.</li>
</ul>



<h3 class="wp-block-heading">Compose Hot Reload MCP</h3>



<p>We now support an MCP server for agents to interact with applications running with Compose Hot Reload.<br><br>To get started, add the following snippet in your <code>mcp.json</code>:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="json" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">{
    "mcpServers": {
        "Compose Hot Reload": {
            "command": "./kotlin",
            "args": [
                "compose-hot-reload-mcp-server"
            ]
        }
    }
}</pre>



<p>With this, agents can interact with, reload, restart, and view window snapshots, and dump the tree of composables. Read more about these capabilities <a href="https://github.com/JetBrains/compose-hot-reload#mcp-server-for-ai-agents" target="_blank" rel="noopener">here</a>.</p>



<h2 class="wp-block-heading">Other improvements</h2>



<h3 class="wp-block-heading">New recommended local dependency format using the <code>//</code> prefix</h3>



<p>Previously, the only way to define local module dependencies was to use relative paths starting with the <code>.</code> (dot) symbol. This approach had several problems. For example, moving a module from one directory level to another required changing all the dependency paths, such as from<code>../../foo</code> to <code>../foo</code>. And having a multitude of <code>../</code> in deeply nested directory structures generally made paths hard to read.</p>



<p>The new recommended way to define local module dependencies is to use project-root-relative paths starting with the <code>//</code> prefix. You might be familiar with this syntax from tools like Bazel. The <code>//</code> prefix represents the project root directory and can be used not only in the <code>dependencies</code> block but in any place that expects a path as well, for example, <code>apply</code>.</p>



<figure class="wp-block-image size-full is-style-default"><img loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/09/before-after.png" alt="" class="wp-image-737392" style="object-fit:cover; width:100% !important; height:auto !important; max-width:100% !important;" /></figure>



<p>The old relative-paths approach still works for now.</p>



<p>This is a step toward allowing multiple modules with the same directory name.</p>



<h2 class="wp-block-heading">Raised minimum JDK and Kotlin versions</h2>



<p>Until now, the minimum JDK version supported by the Kotlin Toolchain was not clearly documented anywhere, and the build would just fail in different places if you used a JDK that was too old. There is now a clear diagnostic and a clear minimum: <strong>only JDK 17 and higher are supported</strong> to compile your code. You can still use <code>settings.jvm.release</code> to set a lower target if your code should be runnable on lower JREs.&nbsp;</p>



<p>The minimum Kotlin compiler version was raised from 2.1.10 to 2.2.20. This allows simplifying our code, and is in line with the <a href="https://blog.jetbrains.com/kotlin/2026/05/security-support-policy-for-the-kotlin-standard-library/">new security support policy</a> for the Kotlin standard library.&nbsp;</p>



<h2 class="wp-block-heading">Updated default versions</h2>



<p>We’ve also updated some of the default versions for built-in toolchains and frameworks:</p>



<ul class="wp-block-list">
<li>Kotlin 2.4.10</li>



<li>JDK 25</li>



<li>JUnit Platform 6.1.3</li>



<li>KSP 2.3.11</li>



<li>Ktor 3.5.2</li>



<li>Spring Boot 4.1.0</li>



<li>DataFrame 1.0.0-rc01</li>



<li>Kotlinx.rpc 0.10.3</li>
</ul>



<h2 class="wp-block-heading">Try Kotlin Toolchain 0.12.0</h2>



<p>To get started with the Kotlin Toolchain, check out our <a href="https://kotl.in/zbd4nw" data-type="link" data-id="https://kotl.in/zbd4nw" target="_blank" rel="noopener"><em>Getting started</em></a> guide. Take a look at some examples, follow the tutorial, or read the comprehensive user guide, depending on your learning style.</p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotl.in/zbd4nw" target="_blank" rel="noopener"><i class="download-icon"></i>Try the Kotlin Toolchain</a></p>



<p>To update an existing project, use the <code>kotlin update</code> command.</p>



<h2 class="wp-block-heading">Share your feedback</h2>



<p>The Kotlin Toolchain is still in Alpha and under active development. You can provide feedback about your experience by joining the discussion in the <a href="https://slack-chats.kotlinlang.org/c/kotlin-toolchain" target="_blank" rel="noopener">#kotlin-toolchain Slack channel</a> (get invite: <a href="https://kotl.in/slack" target="_blank" rel="noopener">https://kotl.in/slack</a>) or by sharing your suggestions and ideas in a <a href="https://youtrack.jetbrains.com/issues/KTC" target="_blank" rel="noopener">YouTrack issue</a>. Your input and use cases help shape the future of the Kotlin Toolchain!</p>



<p></p>
]]></content:encoded>
					
		
		
		                    <language>
                        <code><![CDATA[zh-hans]]></code>
                        <url>https://blog.jetbrains.com/zh-hans/kotlin/2026/09/kotlin-toolchain-0-12-multiplatform-library-publishing-wasm-apps-and-more/</url>
                    </language>
                	</item>
		<item>
		<title>Compose Multiplatform 1.12.0 Released</title>
		<link>https://blog.jetbrains.com/kotlin/2026/08/compose-multiplatform-1-12-0/</link>
					<comments>https://blog.jetbrains.com/kotlin/2026/08/compose-multiplatform-1-12-0/#respond</comments>
		
		<dc:creator><![CDATA[Elvira Mustafina]]></dc:creator>
		<pubDate>Wed, 26 Aug 2026 13:28:41 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/CMP-social-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[releases]]></category>
		<category><![CDATA[compose-for-desktop]]></category>
		<category><![CDATA[compose-for-web]]></category>
		<category><![CDATA[compose-hot-reload]]></category>
		<category><![CDATA[mcp]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=734018</guid>

					<description><![CDATA[Compose Multiplatform 1.12.0 is out! This version brings new tooling for AI assistants, improvements to web resource management, and finer control over desktop window states. Here are the highlights of this release: For a complete overview of the changes, check out What’s new in Compose Multiplatform 1.12.0 or the release notes on GitHub. Get Started [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Compose Multiplatform 1.12.0 is out! This version brings new tooling for AI assistants, improvements to web resource management, and finer control over desktop window states.</p>



<p>Here are the highlights of this release:</p>



<ul class="wp-block-list">
<li><a href="#mcp-server-for-ai-agents-in-compose-hot-reload">MCP server for AI agents in Compose Hot Reload</a></li>



<li><a href="#automatic-font-fallback-for-web">Automatic font fallback for web</a></li>



<li><a href="#window-and-dialog-api-v2">v2 version of the window and dialog API for desktop</a></li>
</ul>



<p>For a complete overview of the changes, check out <a href="https://kotlinlang.org/docs/multiplatform/whats-new-compose-112.html" target="_blank" rel="noopener">What’s new in Compose Multiplatform 1.12.0</a> or the <a href="https://github.com/JetBrains/compose-multiplatform/releases/tag/v1.12.0" target="_blank" rel="noopener">release notes on GitHub</a>.</p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotlinlang.org/docs/multiplatform/compose-multiplatform.html" target="_blank" rel="noopener"><i class="download-icon"></i>Get Started with Compose Multiplatform</a></p>



<h2 class="wp-block-heading">MCP server for AI agents in Compose Hot Reload</h2>



<p>Compose Hot Reload now ships with an experimental Model Context Protocol (MCP) server that connects AI coding agents to your running application.</p>



<p>Using the MCP server, an agent can trigger reloads, take screenshots, inspect the semantic tree, simulate clicks and text input, and read application logs. In practice, this means the agent can verify the results of its own edits. It can confirm that the reload succeeded, inspect the rendered UI, catch a runtime exception, and iterate – all without you describing what&#8217;s on screen.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" style="border-style: solid;border-width: 1px;border-color: lightgray;; width:100% !important; height:auto !important; max-width:100% !important;" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Screenshot-2026-08-25-at-01.36.40.png" alt="AI agent uses the MCP server" class="wp-image-734052"/></figure>



<p>For the full list of available tools and instructions on connecting your agent, see the <a href="https://github.com/JetBrains/compose-hot-reload#mcp-server-for-ai-agents" target="_blank" rel="noopener">Compose Hot Reload documentation</a>.</p>



<p align="center"><a class="ek-link jb-download-button" href="https://kotlinlang.org/docs/multiplatform/compose-hot-reload.html" target="_blank" rel="noopener"><i class="download-icon"></i>Try Compose Hot Reload</a></p>



<h2 class="wp-block-heading">Automatic font fallback for web</h2>



<p>Compose Multiplatform for web now handles characters that your application&#8217;s fonts don&#8217;t cover. When it encounters an unresolved character during rendering, it downloads the matching Noto font subset on demand and recomposes the affected text. As a result, Japanese, Arabic, Devanagari, and emoji render correctly without you having to bundle fonts for them.</p>



<figure class="wp-block-image size-full"><img loading="lazy" decoding="async" style="border-style: solid;border-width: 1px;border-color: lightgray;; width:100% !important; height:auto !important; max-width:100% !important;" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/Screenshot-2026-08-25-at-02.12.16.png" alt="Testing fonts" class="wp-image-734063"/></figure>



<h2 class="wp-block-heading">Window and dialog API v2</h2>



<p>This release introduces an experimental v2 of the API for <code>WindowState</code> and <code>DialogState</code> in the <code>androidx.compose.ui.window.v2</code> package. It gives you finer control over how windows and dialogs are positioned and sized. You can:</p>



<ul class="wp-block-list">
<li>Select the screen a window appears on.</li>



<li>Provide custom positioning and sizing logic, including logic based on the content&#8217;s intrinsic size.</li>



<li>Set minimum and maximum window sizes.</li>



<li>Position dialogs relative to their parent window.</li>
</ul>



<p>The enhanced API also makes the asynchronous nature of window state changes explicit: It distinguishes the state you request from the state the window currently has.</p>



<p>For example, to center a window and give it a fixed size, use <code>WindowPositionProvider</code> and <code>WindowSizeProvider</code>:</p>



<pre class="EnlighterJSRAW EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">val windowState = rememberWindowState(
    initialBoundsProvider = WindowBoundsProvider(
        positionProvider = WindowPositionProvider.CenteredOnScreen,
        sizeProvider = WindowSizeProvider.Fixed(DpSize(400.dp, 200.dp))
    )
)
</pre>



<p>With the API v2, you can also use <code>WindowSizeProvider.Unconstrained</code> to size the window to its content initially, while still letting that content expand with <code>fillMaxSize()</code> when the user enlarges the window:</p>



<pre class="EnlighterJSRAW EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">WindowBoundsProvider(
    positionProvider = WindowPositionProvider.CenteredOnScreen,
    sizeProvider = WindowSizeProvider.Unconstrained
)
</pre>



<p>See the <a href="https://kotlinlang.org/docs/multiplatform/compose-desktop-top-level-windows-management.html#window-and-dialog-api-v2" target="_blank" rel="noopener">Window and dialog API v2 documentation</a> for the full details.</p>



<hr class="wp-block-separator has-alpha-channel-opacity"/>



<p>Update your dependencies, try out the new APIs, and let us know what you think about Compose Multiplatform 1.12.0.</p>



<p>For everything that didn&#8217;t make it into this post, check out the <a href="https://github.com/JetBrains/compose-multiplatform/releases/tag/v1.12.0" target="_blank" rel="noopener">full release notes</a> or <a href="https://kotlinlang.org/docs/multiplatform/whats-new-compose-112.html" target="_blank" rel="noopener">What’s new</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.jetbrains.com/kotlin/2026/08/compose-multiplatform-1-12-0/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
		<title>Signatures, be true: domain errors and functional handling in Kotlin</title>
		<link>https://blog.jetbrains.com/kotlin/2026/08/signatures-be-true-domain-errors-and-functional-handling-in-kotlin/</link>
		
		<dc:creator><![CDATA[Alina Dolgikh]]></dc:creator>
		<pubDate>Wed, 19 Aug 2026 15:52:05 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/KT-social-BlogFeatured-1280x720-1-1.png</featuredImage>		<category><![CDATA[backend]]></category>
		<category><![CDATA[kotlin]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=732373</guid>

					<description><![CDATA[Here’s a function that signs a document: In Kotlin, Unit means the function completes without returning a meaningful value – roughly equivalent to void in Java. Got it? Now, tell me what could go wrong. You can’t.&#160; Yet, the code might be invalid. The signing window might have closed. The database might be down. The [&#8230;]]]></description>
										<content:encoded><![CDATA[

    <div class="about-author ">
        <div class="about-author__box">
            <div class="row">
                                                            <div class="about-author__box-img">
                            <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/2026-08-18-15.29.34.jpg" alt="Sergey Chernov" loading="lazy">
                        </div>
                                        <div class="about-author__box-text">
                                                    <h4>Sergey Chernov</h4>
                                                <p>Sergey Chernov is a Lead Software Engineer at Salmon, specializing in functional Kotlin and type-safe system design. At Salmon, a technology-driven financial company building banking and lending products in Southeast Asia, Sergey works on authentication and verification systems: the platform layer responsible for keeping user access secure, reliable, and consistent across products. He has 10+ years of experience designing and building scalable backend systems.</p>
                    </div>
                            </div>
        </div>
    </div>



<p>Here’s a function that signs a document:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun signDocument(
    documentId: UUID,
    code: String,
): Unit</pre>



<p>In Kotlin, <code>Unit</code> means the function completes without returning a meaningful value – roughly equivalent to <code>void</code> in Java.</p>



<p>Got it? Now, tell me what could go wrong. <em>You can’t</em>.&nbsp;</p>



<p>Yet, the code might be invalid. The signing window might have closed. The database might be down. The document might already be signed, or expired, or the request might have arrived out of order from a buggy client.&nbsp;</p>



<p>Every one of those is a real outcome this function must reckon with. Not one is visible in the line above.</p>



<p>To discover possible failures and how to handle them, you could open the implementation. Then, the service it calls. Then, the exception handlers, the route mapping, the tests, the OpenAPI spec, and the client code that consumes it.&nbsp;</p>



<p>You could read everything except the one thing that should have told you in the first place: <strong>the signature</strong>.</p>



<p>At Salmon, I work on authentication and verification. A mishandled failure is rarely cosmetic and the difference between two error cases can be the difference between letting the right person through and the wrong one. I’ve spent a fair bit of time on this question: <strong>how do you make a function’s expected failures part of what it tells you, instead of something you have to go digging for</strong>?&nbsp;</p>



<p>This article is my answer. It uses Kotlin, but the concept carries to any language with sealed types.</p>



<h2 class="wp-block-heading">Have no fear of “functional error handling”</h2>



<p>“<em>Functional error handling</em>”. That phrase scares people off. They expect monads, category theory, and a lecture. This isn’t the case. The goal is plain: the function signature should be enough to know how to call it and how to handle every expected outcome. Nothing hidden in the body.&nbsp;</p>



<p>If a failure is part of the business logic, it belongs in the function signature, the API contract, and the client’s handling code, not buried in the implementation.</p>



<p>Salmon&#8217;s engineering culture runs on a few commitments: real ownership from day one, high standards held in the open, and a refusal to ship things that don&#8217;t actually work. A function that hides its failures is at odds with all three.&nbsp;</p>



<p>So, in the case of the example above, the signature I actually want should look like this:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun signDocument(
    documentId: UUID,
    code: String,
): Either&lt;DocumentSignError, Unit></pre>



<p>We now have the inputs on the left of the function and the expected failure type and the success type on the right.&nbsp;</p>



<p>Now, before we get to what <code>Either</code> is, we need to agree on what belongs inside <code>DocumentSignError</code> in the first place, because that’s where a lot of the value of this system comes from.</p>



<h2 class="wp-block-heading"><strong>Three kinds of failure, but only one belongs in the signature</strong></h2>



<p>Not every bad thing that happens is the same kind of bad thing. I split failures into three groups, and each group gets handled differently.</p>



<h3 class="wp-block-heading"><strong>01 · API CLIENT ERRORS</strong></h3>



<p>The caller used the API wrong: this means a malformed JSON, a missing header, an unsupported operation, a request that arrived out of sequence, access that isn’t allowed.&nbsp;</p>



<p>A healthy client should almost never see these, and there is no designed screen for them, because a working app doesn’t produce them. Thus, you can collapse the whole category into coarse HTTP responses: a 400, a 403, a 404. You do not enumerate them one by one in your domain model<strong>.</strong></p>



<h3 class="wp-block-heading"><strong>02 · UNEXPECTED EXCEPTIONS</strong></h3>



<p>The database is unavailable. A dependency timed out. The network dropped. A null slipped through and you have a <code>NullPointerException</code>, or an invariant broke and you’re in an illegal state. These are <em>not</em> business outcomes.&nbsp;</p>



<p>Nobody designs a user flow for “Postgres fell over.” You do not model these as domain errors. Instead, they become operational signals: a 500 to the client, a full stack trace in the logs, a spike in your error-rate metric, a page to whoever is on call.</p>



<h3 class="wp-block-heading"><strong>03 · DOMAIN ERRORS</strong></h3>



<p>Here, the client behaved correctly, yet the operation still can’t succeed.&nbsp;</p>



<p>The signing code was wrong. The window has closed. The document was already signed. Approval is missing. The policy rejected it. These are the failures a real user hits while doing everything right, and your designers have a specific screen for each one.&nbsp;</p>



<p>This is the category that has to be visible. If a healthy client needs to handle two outcomes differently, those two outcomes have to be distinguishable in the type. <strong>This is the group that belongs in the contract.</strong></p>



<p>I often see people mistakenly dragging the second group into the other two. For instance, people add <strong><code>DatabaseUnavailable</code></strong> to their error union as if it were a business failure. It isn’t. Let it throw, let the global handler catch it, and keep your domain model honest. </p>



<p><code>HTTP 400</code> is not a domain concept. “Signing window closed” is.</p>



<p>In any case, if you recognize and split these three categories correctly, most of the design work is already done. The rest is choosing a mechanism that keeps the second group visible.</p>



<h2 class="wp-block-heading">Why exceptions and their relatives keep losing</h2>



<p>The default in most Java and Kotlin codebases is to validate, then throw:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun signDocument(documentId: UUID, code: String) {
    if (signingWindowClosed(documentId)) throw SigningWindowClosedException()
    if (!codeMatches(documentId, code)) throw SignatureRejectedException()
    if (alreadySigned(documentId)) throw AlreadySignedException()
    // ... sign it
}</pre>



<p>The signature says “returns nothing, succeeds.” But the implementation tells a different story, and the compiler will not make the caller listen to it. If someone adds a fourth exception next quarter, every call site still compiles, and every call site silently fails to handle the new case. You find out in production, and that’s not great.</p>



<p>Java tried to fix this with checked exceptions, and the instinct was right: force the caller to handle declared failures or pass them on. But it didn’t scale. And the Stream API doesn’t compose with checked exceptions at all, so you end up doing sneaky throws and wrapping everything back into runtime exceptions.</p>



<p>As it turns out, the better tool is already in the language itself. A sealed interface tells the compiler the complete set of subtypes, this means that when you handle these errors (using Kotlin’s <code>when</code> expression), the compiler can safely verify you haven&#8217;t missed a single case:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sealed interface DocumentSignError {
    data object SignatureRejected   : DocumentSignError
    data object SigningWindowClosed : DocumentSignError
    data object AlreadySigned       : DocumentSignError
}</pre>



<p>Now the caller handles every case, and the compiler enforces it:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">when (error) {
    SignatureRejected   -> showSignatureRejected()
    SigningWindowClosed -> showSigningWindowClosed()
    AlreadySigned       -> showAlreadySigned()
}</pre>



<p>Add a fourth failure to the sealed interface and this <strong><code>when</code></strong> stops compiling until you handle it. And this is the whole game: the compiler now knows what <em>can</em> fail, and it won’t let you forget.</p>



<h2 class="wp-block-heading"><strong>You just reinvented Either</strong></h2>



<p>Once you have a sealed error type, you need a way to say “this function returns either that error or a success.” You can build a wrapper by hand, and people do, for each result type, over and over. That gets verbose fast.</p>



<p>What you’re reaching for is a generic version of the same shape: a value that is one thing or the other, never both. Left for the failure, right for the success. That is <strong><code>Either</code></strong>, and you don’t need a library to understand it. It’s a sealed type with two cases and a handful of helper methods (<strong><code>map</code></strong>, <strong><code>flatMap</code></strong>, <strong><code>fold</code></strong>, <strong><code>getOrElse</code></strong>). If you’ve used <strong><code>Optional</code></strong> in Java or nullable types in Kotlin, you already know how it feels to work with. An <strong><code>Optional</code></strong> is roughly an <strong><code>Either</code></strong> whose left side carries no information, just <strong><code>Unit</code></strong>.</p>



<p>The payoff is that the failure set moves into the public type:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun signDocument(
    documentId: UUID,
    code: String,
): Either&lt;DocumentSignError, Unit></pre>



<p>Failures are no longer hidden in the function body; they are part of what the function tells you upfront.</p>



<h2 class="wp-block-heading"><strong>Two unions people get wrong</strong></h2>



<p>Unfortunately, two anti-patterns show up constantly once teams adopt this, and both undo most of the benefit.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">fun signDocument(documentId: UUID, code: String): 
Either&lt;Throwable, Unit></pre>



<p>While this looks typed, the type says only “something can fail.” It does not say which expected failures the caller must handle, because <strong><code>Throwable</code></strong> is open, so a <strong><code>when</code></strong> over it always needs an <strong><code>else</code></strong>. You’re back to not knowing.&nbsp;</p>



<p>This is essentially the same as throwing an error, and it’s why Kotlin’s own <strong><code>Result&lt;T&gt;</code></strong> type didn’t work out and isn’t recommended for domain modeling. If the left side is open, you’ve gained nothing.</p>



<p>The second is one broad union shared across a whole class, in the name of not repeating yourself:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sealed interface DocumentError {
    data object SignatureRejected   : DocumentError
    data object SigningWindowClosed : DocumentError
    data object AlreadySigned       : DocumentError
    data object TemplateNotFound    : DocumentError
    data object ExportFailed        : DocumentError
}
 
fun signDocument(...)     : Either&lt;DocumentError, Unit>
fun prepareSigning(...)   : Either&lt;DocumentError, SigningSession>
fun exportDocument(...)   : Either&lt;DocumentError, ExportFile></pre>



<p>The compiler is happy, but now every method appears to return every error. <strong><code>signDocument</code></strong> can never produce <strong><code>TemplateNotFound</code></strong>, yet every caller has to account for it anyway. You get exhaustive handling full of impossible branches, which is just catch-all programming wearing a type.</p>



<p>The fix is to define one narrow union per public method:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">sealed interface DocumentSignError { /* the three real failures */ }
sealed interface PrepareSigningError { /* its own set */ }
sealed interface ExportError { /* its own set */ }</pre>



<p>Then each <strong><code>when</code></strong> handles only what its method can actually return. No <strong><code>else</code></strong> or impossible cases:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">when (error) {
    SignatureRejected   -> showSignatureRejected()
    SigningWindowClosed -> showSigningWindowClosed()
    AlreadySigned       -> showAlreadySigned()
}</pre>



<p>A little more typing up front, but worth it every single time you read one of these signatures later.</p>



<h2 class="wp-block-heading"><strong>Composition, without drowning in the plumbing</strong></h2>



<p>Real flows chain steps, and each step can fail. Done naively with <strong><code>flatMap</code></strong>, the lambdas nest deeper with every step and the code gets ugly.&nbsp;</p>



<p>You have a few ways out. Plain Kotlin handles it with early return:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">val document = findDocument(documentId)
    .getOrElse { return it.left() }</pre>



<p>Flat, typed, and the pattern itself needs no library: if you hand-roll <strong><code>Either</code></strong>, you write these helpers yourself. The syntax above happens to use <code><strong>Arrow’s</strong> <strong>getOrElse</strong></code> and <strong><code>left</code></strong>, but nothing here depends on the abstraction being fancy.&nbsp;</p>



<p>If you want it cleaner, <strong><code>Arrow</code></strong> also gives you an <strong><code>either { }</code></strong> block where <strong><code>bind()</code></strong> unwraps a right value and short-circuits on the first left:</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">either {
    val document = findDocument(documentId).bind()
    validateStatus(document).bind()
    val signature = validateSignature(document, code).bind()
    markSigned(document, signature).bind()
}</pre>



<p>This is the same idea Scala has had in the language for years with for-comprehensions. Use <strong><code>Arrow</code></strong> if the ergonomics help your team; it also brings useful types like non-empty lists. (But the contract idea does not depend on <strong><code>Arrow</code></strong>, and I’d rather you adopt the discipline than the dependency.)</p>



<h2 class="wp-block-heading"><strong>The contract should survive the whole trip</strong></h2>



<p>A typed failure is only useful if it stays typed across the stack. Here’s the rule I hold to: services and repositories return domain errors, and you map to HTTP at exactly one place, the route boundary.</p>



<pre class="EnlighterJSRAW" data-enlighter-language="kotlin" data-enlighter-theme="" data-enlighter-highlight="" data-enlighter-linenumbers="" data-enlighter-lineoffset="" data-enlighter-title="" data-enlighter-group="">service.signDocument(request)
    .mapLeft { error -> error.toHttpResponse() }</pre>



<p>Expected domain failures become an <strong><code>Either.Left</code></strong>. API-client misuse collapses to a coarse 4xx. Unexpected infrastructure failures and bugs stay as exceptions and become a 500. The controller is the only layer that knows about HTTP, and the layers beneath it speak in business outcomes.</p>



<p>There’s also a bonus most teams don’t realize here: If you publish your API client alongside the service, publish the error types with it. If you do this, the client handles failures with the same sealed union the server produces, and the two stay consistent for free.</p>



<h2 class="wp-block-heading"><strong>How does this impact code review, and AI-generated code?</strong></h2>



<p>The day-to-day return on all of this shows up in review. When failures live in the signature, a reviewer can start from the contract instead of doing implementation archaeology. Did the error union change? Is this API-client misuse dressed up as a domain error? Does the new failure map to HTTP? You can answer those by reading the interface, before you ever open the body.</p>



<p>At Salmon and elsewhere, this agility matters more now that a large share of code is drafted by agents.&nbsp;</p>



<p>When a model writes the implementation, an explicit contract is the cheapest way to check whether it did the right thing: you read the types, not the 200 lines underneath. You can put the rule in an agent instructions file, “<em>return a typed error union, don’t throw for expected failures,</em>” and the model will mostly follow it. But the way you verify is by reading the contract, not by trusting the prose.&nbsp;</p>



<p>In fact, on our team at Salmon this is less a personal preference than a shared default: the contract is the unit of review, and a generated implementation doesn’t lower that bar. Deciding which failures an operation can actually produce is a judgment call, and the signature is where that judgment gets written down so the next person, or the next agent, has to respect it. Essentially, the signature is where ownership lives.</p>



<h2 class="wp-block-heading"><strong>The honest tradeoff</strong></h2>



<p>This costs you something. More types, more mapping code, more verbose signatures. I won’t pretend otherwise.&nbsp;</p>



<p>But the complexity was already there. The signing window could always close. The code could always be wrong. All this approach does is take that complexity out of the implementation, where it was hiding, and put it in the type, where it’s named, tested, and visible.<br><br>You are simply moving the work to where the compiler can help. It surfaces risk to the next caller instead of hiding it, makes clear what the code really does and stops broken paths from compiling. Making failures part of the signature is how those values show up at the smallest scale: one function telling the truth about what it can do. It is also how we work in practice at Salmon: we share these typed contracts across services and their clients, and in review we read the contract before the implementation.</p>



<p>A signature that returns <strong><code>Unit</code></strong> and throws in secret is lying to you about what it does. Make your signatures tell the truth!</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Klibs.io Grows to 4,200+ KMP Projects With Smarter Discovery and New AI Integrations</title>
		<link>https://blog.jetbrains.com/kotlin/2026/08/klibsio-grows-to-4200-kmp-projects-with-smarter-discovery-and-new-ai-integrations/</link>
		
		<dc:creator><![CDATA[Daria Voronina]]></dc:creator>
		<pubDate>Mon, 17 Aug 2026 13:12:57 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/KM-social-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[kotlin-multiplatform-libraries]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=731768</guid>

					<description><![CDATA[Explore a growing Kotlin Multiplatform catalog in your browser, or bring up-to-date library data directly into your AI development workflow through the klibs.io MCP server. When we introduced klibs.io in December 2024, the goal was simple: make it easier to find a Kotlin Multiplatform library that fits both your use case and target platforms. Since [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Explore a growing Kotlin Multiplatform catalog in your browser, or bring up-to-date library data directly into your AI development workflow through the klibs.io MCP server.<br><br>When we<a href="https://blog.jetbrains.com/kotlin/2024/12/introducing-klibs-io-a-new-way-to-discover-kotlin-multiplatform-libraries/" target="_blank" rel="noreferrer noopener"> introduced klibs.io in December 2024</a>, the goal was simple: make it easier to find a Kotlin Multiplatform library that fits both your use case and target platforms. Since then, klibs.io has grown into a catalog of more than 4,200 KMP projects – and discovering new libraries has become even easier.</p>



<div class="buttons">
    <div class="buttons__row">
        <a class="ek-link jb-download-button" title="Explore Kotlin Multiplatform projects on klibs.io" href="https://klibs.io/" target="_blank" rel="noopener" data-test="blog-article-cta" data-cl="true">Explore Kotlin Multiplatform projects on klibs.io</a>
    </div>
</div>



<h2 class="wp-block-heading"><strong>Discover more than 4,200+ KMP projects</strong></h2>



<p>klibs.io combines information from GitHub and Maven Central, bringing the details needed to evaluate a project into a single catalog. When source metadata is incomplete, klibs.io uses LLMs to refine descriptions and tags, improving search and discoverability.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/klibsio-4200-projects-by-tags.png" alt="" class="wp-image-731771"/></figure>



<p>Discovery now goes well beyond a basic keyword search. Use multiple search terms, filter by supported platforms and targets – including Android, iOS, JVM, JavaScript, and Wasm – and browse curated categories such as Compose UI, local storage, networking, or dependency injection. Results can be sorted by relevance, GitHub stars, or dependent count.</p>



<p>Project pages make comparison easier by bringing together descriptions, tags, <code>README</code> content, supported platforms, package versions, dependent counts, license information, and project activity. </p>



<p>This gives you a clearer view of whether a library fits your project before you add the dependency.</p>



<aside role="note" style="margin: 24px 0; padding: 16px 20px; background: #f5f2ff; border-left: 4px solid #7f52ff; border-radius: 8px; color: #27282c; line-height: 1.6;">
    <p style="margin: 0;">
        <strong style="color: #5936c7;">TIP:</strong>
        Explore klibs.io’s
        <a href="https://klibs.io/?category=grant-winners" target="_blank" rel="noopener noreferrer" style="color: #5936c7; font-weight: 600;">
            Grant winners
        </a>
        category – KMP libraries recognized by the Kotlin Foundation Grants Program for their quality and impact.
    </p>
</aside>



<h2 class="wp-block-heading"><strong>Bring klibs.io into your AI workflow</strong></h2>



<p>Library decisions often happen while you are already coding. The new AI integrations allow coding agents to pull structured, up-to-date data from klibs.io rather than relying solely on training data or a general web search.</p>



<h3 class="wp-block-heading"><strong>Connect through the klibs.io MCP server</strong></h3>



<p>The<a href="https://github.com/JetBrains/klibs-io/tree/master/integrations/mcp#readme" target="_blank" rel="noreferrer noopener"> klibs.io MCP server</a> lets agents search Kotlin Multiplatform projects by platform and target and retrieve the latest published package versions directly from the klibs.io index.</p>



<h3 class="wp-block-heading"><strong>Give agents reusable KMP library expertise</strong></h3>



<p>The<a href="https://klibs.io/ai#skill" target="_blank" rel="noreferrer noopener"> Kotlin Multiplatform Libraries expert skill</a> provides task-specific instructions for discovering and comparing libraries, recommending options for a use case, verifying platform support, and finding up-to-date dependency coordinates and stable versions. We measured agent output with and without klibs.io connected – the <a href="https://github.com/JetBrains/klibs-io/blob/f42d394e3b1a18757193241386aec7753437dc62/mcp-eval/RESULTS.md" target="_blank" rel="noreferrer noopener">evaluation results</a> are published in the klibs.io repository.</p>



<h3 class="wp-block-heading"><strong>Keep project guidance close to the code</strong></h3>



<p>The<a href="https://klibs.io/ai#overview" target="_blank" rel="noopener"> AI integration guide</a> includes setup instructions and a<a href="https://klibs.io/ai#agents" target="_blank" rel="noreferrer noopener"> recommended AGENTS.md snippet</a>. Adding guidance to a project helps AI tools consistently use verified information from the KMP library.</p>



<div class="buttons">
    <div class="buttons__row">
        <a class="ek-link jb-download-button" title="Explore AI development with klibs.io" href="https://klibs.io/ai#overview" target="_blank" rel="noopener" data-test="blog-article-cta" data-cl="true">Explore AI development with klibs.io</a>
    </div>
</div>



<h2 class="wp-block-heading"><strong>Help shape what comes next</strong></h2>



<p>klibs.io is an open-source project, and feedback from library users and authors helps the catalog keep improving. Here are a few ways to take part:</p>



<p>•&nbsp; <strong>Try it out: </strong>Search for a library, explore a category, and see how the filters work for your target platforms.</p>



<p>•&nbsp; <strong>Improve project information: </strong>Project owners can use the <em>Suggest an edit</em> option on project pages to propose better descriptions and tags through GitHub.</p>



<p>•  <strong>Report issues or contribute: </strong>Report bugs, missing libraries, or incorrect metadata in the<a href="https://github.com/JetBrains/klibs-io/issues/new/choose" target="_blank" rel="noreferrer noopener"> GitHub issue tracker</a>, or contribute directly to the<a href="https://github.com/JetBrains/klibs-io" target="_blank" rel="noreferrer noopener"> open-source project</a>.</p>



<p>•  <strong>Join the discussion: </strong>Share feedback in the<a href="https://kotlinlang.slack.com/archives/C081AF4JK70" target="_blank" rel="noreferrer noopener"> #klibs-io channel on Kotlin Slack</a>.<br></p>



<p>Whether you browse the catalog directly or integrate it with your AI tools, klibs.io now makes it easier to discover, compare, and use Kotlin Multiplatform libraries with up-to-date information.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Exploring Compose HTML for Server Side Rendering</title>
		<link>https://blog.jetbrains.com/kotlin/2026/08/exploring-compose-html-for-server-side-rendering/</link>
		
		<dc:creator><![CDATA[Frederik Pietzko]]></dc:creator>
		<pubDate>Fri, 14 Aug 2026 12:15:09 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/KT-social-BlogFeatured-1280x720-1.png</featuredImage>		<category><![CDATA[backend]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[compose-multiplatform]]></category>
		<category><![CDATA[server]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=731283</guid>

					<description><![CDATA[Something is happening in server-rendered web development. React shipped Server Components. HTMX made &#8220;hypermedia&#8221; cool again. Phoenix LiveView proved a server can push interactive UI updates without a client framework in sight. Every ecosystem seems to be rediscovering the server as a place to render UI, except one: the JVM. What if Compose, the UI [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Something is happening in server-rendered web development. React shipped Server Components. HTMX made &#8220;hypermedia&#8221; cool again. Phoenix LiveView proved a server can push interactive UI updates without a client framework in sight. Every ecosystem seems to be rediscovering the server as a place to render UI, except one: the JVM. What if Compose, the UI toolkit already spanning Android, Desktop, and iOS, took a shot at server-rendering HTML too?</p>



<p>The vision is simple: give backend developers a way to build server-rendered UI as type-safe, reusable Compose components (real Kotlin, with autocomplete, refactoring, and compiler checks) instead of string-based templates. No separate templating language, no separate UI codebase to maintain alongside the backend. This blog serves to explore some ideas how to achieve this vision and represents an exploration instead of an official commitment.</p>



<p>Every major JS framework now has an SSR story: React has Next, Vue has Nuxt, Svelte has SvelteKit. And it&#8217;s not only the JS ecosystem. C#, Rust and even functional languages like Elixir have innovative solutions to build fullstack apps without relying on templating engines. Instead, they bundle state and rendering into reusable components, directly in code, the same way Compose already does everywhere else.</p>



<p>Right now the JVM doesn&#8217;t have a horse in this race. There&#8217;s no shortage of SSR libraries on the JVM. But most of them need some sort of templating language and have nothing close enough to a component for a JS dev to recognize as such.</p>



<p>But there is already a framework that is battle-tested and capable of filling this gap for the JVM, it just never really targeted the server. Compose Multiplatform allows us to write business logic and User Interfaces once and share it between platforms: Android, iOS, Desktop, and the web. It just needs to make the jump to the server next.</p>



<p>Compose Multiplatform already targets the web, but not the way you&#8217;d want for this: it renders directly into a canvas, which shares UI code between mobile platforms and the browser at the cost of SEO, loading times, and accessibility.</p>



<p>A way to render HTML with Compose already exists, and it&#8217;s older than Compose for Web: Compose HTML, which uses the Compose runtime to build SPAs in Kotlin and compile it to JS using the Kotlin/JS compiler. Add a JVM target and it could do SSR too. The rendering happens directly in Kotlin: real components, real types, no templating language.</p>



<p>JVM devs stuck with Thymeleaf/JSP, or reaching for a separate JS framework just to build fullstack applications, wouldn&#8217;t have to leave the platform: type-safe, reusable Compose components replace what the templating language used to handle. Kotlin&#8217;s Java interoperability means it would slot into large legacy Java applications too.</p>



<p>Take something as basic as a reusable card component. In Thymeleaf, that&#8217;s a fragment defined in its own file, called by name, with parameters passed as untyped strings:</p>



<pre class="EnlighterJSRAW">&lt;!-- fragments/card.html --&gt;
&lt;div th:fragment=&quot;card(title, count)&quot; class=&quot;card&quot;&gt;
	&lt;h3 th:text=&quot;${title}&quot;&gt;Title&lt;/h3&gt;
	&lt;span th:text=&quot;${count}&quot;&gt;0&lt;/span&gt;
&lt;/div&gt;
&lt;!-- usage --&gt;
&lt;div th:replace=&quot;~{fragments/card :: card(title=&#039;Cart&#039;, count=${cartCount})}&quot;&gt;&lt;/div&gt;
&lt;div th:replace=&quot;~{fragments/card :: card(title=&#039;Wishlist&#039;, count=${wishlistCount})}&quot;&gt;&lt;/div&gt;</pre>



<p>Rename <code>count</code> to <code>itemCount</code> and every call site keeps compiling until it breaks at runtime. The compiler has no idea <code>card</code> or its parameters even exist.</p>



<p>The same component in Compose is a typed function:</p>



<pre class="EnlighterJSRAW">@Composable
fun Card(title: String, count: Int) {
	Div({ classes(&quot;card&quot;) }) {
		H3 { Text(title) }
		Span { Text(count.toString()) }
	}
}
// usage
Card(title = &quot;Cart&quot;, count = cartCount)
Card(title = &quot;Wishlist&quot;, count = wishlistCount)</pre>



<p>Rename <code>count</code> here and every call site either updates with the IDE or fails to compile. Pass a <code>String</code> where an <code>Int</code> is expected, and it&#8217;s a compiler error, not a runtime surprise.</p>



<p>Today Compose HTML only has a JS target, so it can only be used from the browser; there&#8217;s no way of doing SSR yet. That doesn&#8217;t mean the Kotlin web-dev ecosystem is standing still, though.</p>



<p>There is<a href="https://kobweb.varabyte.com/" target="_blank" rel="noopener"> Kobweb</a>, a batteries-included framework built on top of Compose HTML. It doesn&#8217;t offer SSR but supports static site export/prerendering to help with SEO. There is also<a href="https://kilua.dev/" target="_blank" rel="noopener"> Kilua</a>, which doesn&#8217;t build on top of Compose HTML but on top of the Compose Runtime directly to do SSR and CSR, leveraging JS or Wasm, and offers integrations for Ktor, Spring Boot, and others. And there is<a href="https://github.com/codeyousef/summon" target="_blank" rel="noopener"> Summon</a>, with SSR and hydration support.</p>



<p>There&#8217;s already a small but active community leveraging Compose to build for the web. Adding SSR capabilities to Compose HTML would give Kobweb, Kilua, and Summon a shared foundation instead of three separate approaches, and give frameworks like Spring Boot and Ktor a good reason to integrate with it on the server.</p>



<p>This space isn&#8217;t totally unexplored, but everything from this point onward is pure exploration.</p>



<h2 class="wp-block-heading"><strong>What Compose HTML on the server could look like</strong></h2>



<p>The first step would be to add a JVM target to Compose HTML, which is a bit easier said than done. There would need to be <code>renderToString</code> and <code>renderToBytes</code> functions that run a composition once on the JVM and serialize the resulting tree into a string.<br></p>



<pre class="EnlighterJSRAW">fun renderToString(content: @Composable DOMScope&lt;DomElement&gt;.() -&gt; Unit): String

val html: String = renderToString {
    Div({ classes(&quot;card&quot;) }) {
        Text(&quot;Hello&quot;)
        Span({ classes(&quot;title&quot;) }) {
            Text(&quot;World&quot;)
        }
    }
}
// html == &quot;&quot;&quot;&lt;div class=&quot;card&quot;&gt;Hello&lt;span class=&quot;title&quot;&gt;World&lt;/span&gt;&lt;/div&gt;&quot;&quot;&quot;</pre>



<p>It composes once, lets the initial composition settle, walks the resulting tree, and serializes it straight to an HTML string: no browser, no DOM.</p>



<p>There are some limitations to this. There would probably be only a single render pass, meaning no recomposition on state change or any effects, in essence very similar to SSR in JS. Event listeners should be accepted but will be inert; there&#8217;s no point in binding to browser events on the server.</p>



<p>This would probably already be enough to build basic, entirely server-rendered pages using Compose. Here&#8217;s a full todo app on Spring Boot:</p>



<pre class="EnlighterJSRAW">@Controller
class TodoController(private val todoService: TodoService) {

    @GetMapping(&quot;/todos&quot;)
    @ResponseBody
    fun todoView(): String = renderToString {
        TodoView(todoService)
    }

    @PostMapping(&quot;/todos&quot;)
    fun addTodo(createTodoDto: CreateTodoDto): String {
        todoService.addTodo(createTodoDto.title)
        return &quot;redirect:/todos&quot;
    }

    @PostMapping(&quot;/complete/{id}&quot;)
    fun completeTodo(@PathVariable id: Long): String {
        todoService.completeTodo(id)
        return &quot;redirect:/todos&quot;
    }
}

data class CreateTodoDto(val title: String)

@Composable
fun TodoView(todoService: TodoService) {
    AddTodo()
    TodoList(todoService)
}

@Composable
fun AddTodo() {
    Form(
        attrs = {
            action(&quot;/todos&quot;)
            method(FormMethod.Post)
        }
    ) {
        TextInput(
            attrs = {
                placeholder(&quot;Add todo&quot;)
                name(CreateTodoDto::title.name)
            }
        )
        Button(
            attrs = {
                type(ButtonType.Submit)
            }
        ) {
            Text(&quot;Add&quot;)
        }
    }
}

@Composable
fun TodoList(todoService: TodoService) {
    val todos by produceState(initialValue = emptyList&lt;Todo&gt;(), todoService) {
        value = todoService.getTodos()
    }
    Ul {
        todos.forEach { todo -&gt;
            Li {
                Form(
                    attrs = {
                        action(&quot;/complete/${todo.id}&quot;)
                        method(FormMethod.Post)
                    }
                ) {
                    Text(todo.title)
                    Button(
                        attrs = {
                            type(ButtonType.Submit)
                        }
                    ) {
                        Text(&quot;Complete&quot;)
                    }
                }
            }
        }
    }
}</pre>



<p>Every interaction here is a real HTTP form submission and full-page redirect: no client JS at all, same as classic Thymeleaf-style SSR, just written entirely in Compose.</p>



<p>At that point, frameworks like Spring and Ktor could start experimenting with integrations and identifying missing integration points. This would also be the first sensible point at which new libraries (e.g. components) could be created.</p>



<p>Going entirely off the rails into pure speculation, this is what such an integration could look like for Spring:</p>



<pre class="EnlighterJSRAW">@ComposePage(&quot;/todos&quot;)
@Composable
fun TodosPage(todoService: TodoService) {
    AddTodo()
    TodoList(todoService)
}

@ComposeAction(&quot;/todos&quot;, method = PostMapping::class)
fun addTodo(
    @RequestBody createTodoDto: CreateTodoDto,
    todoService: TodoService
) {
    todoService.addTodo(createTodoDto.title)
}</pre>



<p>The idea: a hypothetical Spring integration could turn a <code>@Composable</code> function directly into a routed page, no manual <code>renderToString</code> call, no controller boilerplate, no wrapping HTML shell. Spring would own request mapping and dependency injection exactly like it does today; Compose HTML would just be the render target instead of a <code>View/template</code>.</p>



<p>Or for Ktor:</p>



<pre class="EnlighterJSRAW">routing {
    composable(&quot;/todos&quot;) {
        TodoView(todoService)
    }

    post(&quot;/todos&quot;) {
        val params = call.receiveParameters()
        todoService.addTodo(params&#091;&quot;title&quot;]!!)
        call.respondRedirect(&quot;/todos&quot;)
    }
}</pre>



<p><code>composable(path) { }</code> would be a thin wrapper Ktor could add: call <code>renderToString</code> internally and respond with the HTML content type, so a route body becomes a <code>@Composable</code> lambda instead of a string template or manual <code>call.respondText</code>.</p>



<p>Worth repeating: these are illustrative sketches, not planned APIs, not a roadmap.</p>



<p>Hydration and state sync are the natural next question, not an answer: how would a composable that already rendered on the server pick up interactivity in the browser, and would client and server ever need to agree on state? Answering that would also open the door to sharing UI code between client and server, the same component compiled once for the browser and once for the server, and enable interactive fullstack web apps built entirely in Kotlin.</p>



<p>Let&#8217;s be clear about scope: the goal is not to expand Compose HTML into a fully-fledged, batteries-included framework. Rather, the vision is similar to React&#8217;s: stay small and let frameworks build the integration points on top, just applied to a multiplatform library instead of a single-platform one. Framework integrations and ecosystem libraries live outside the core. That&#8217;s a real contrast to the rest of Compose Multiplatform, which ships official libraries for Material3 components, state management, and many other things. Compose HTML will need to rely on the Kotlin community and ecosystem to figure out what integration points are actually needed and how its future will look, instead of dictating a direction from the inside.</p>



<p>We are already talking to framework maintainers from Kobweb, Kilua, and Summon to gather their perspective, as well as the Spring team, which has expressed interest in experimenting once a JVM target is added to Compose HTML.</p>



<p>If you want to talk shop, argue with any of this, or just see where it goes, join the Kotlinlang Slack (get your invite here: <a href="https://kotl.in/slack" target="_blank" rel="noopener">https://kotl.in/slack</a>) and the <a href="https://kotlinlang.slack.com/archives/C0BM8FWG58Q" target="_blank" rel="noopener">#compose-ssr</a> channel.</p>



<p>Every other ecosystem already took its shot at the server. Kotlin&#8217;s turn is overdue.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>When Escape Routes Become Toll Roads: Mapping How Developers Move Between Programming Languages</title>
		<link>https://blog.jetbrains.com/research/2026/08/programming-language-migration/</link>
		
		<dc:creator><![CDATA[Vladimir Volokhonsky]]></dc:creator>
		<pubDate>Wed, 12 Aug 2026 16:15:18 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/08/JB-social-BlogFeatured-1280x720-1-1.png</featuredImage>		<product ><![CDATA[kotlin]]></product>
		<category><![CDATA[articles-2]]></category>
		<category><![CDATA[deveco]]></category>
		<category><![CDATA[research]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=research&#038;p=729328</guid>

					<description><![CDATA[TL;DR: This post relates findings about language migration from the 2025 State of Developer Ecosystem survey. In general, project requirements are still the most common reasons for switching languages. One outlier from this trend, however, is Kotlin. People switch to Kotlin not because they have to; they switch because it simply feels better to work [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><em>TL;DR: This post relates findings about language migration from the 2025 State of Developer Ecosystem survey. In general, project requirements are still the most common reasons for switching languages. One outlier from this trend, however, is Kotlin. People switch to Kotlin not because they have to; they switch because it simply feels better to work with, thanks to its better development experience and more modern features. C has a surprisingly high churn rate, and Java developers tend to move to Python and TypeScript. HTML/CSS developers learn JavaScript to improve their job opportunities, while JavaScript developers switch to almost everything else for the same reason.</em></p>



<h3 class="wp-block-heading"><strong>The history of programming is, in part, a history of escape</strong></h3>



<p><br>Ada Lovelace wrote for a machine that did not yet exist in working form. A century later, programmers were wrestling with machines that had switches, punched cards, and raw numeric instructions. Then came assembly, and with it the first great bargain of software: give up a little closeness to the machine, and gain a little room for the human mind. But history does not stand still. With new languages and shifts in context, aspects of existing languages began to get in the way.<br><br>One language moved to such a high level of abstraction that its efficiency in the physical reality of the machine stopped holding up. Meanwhile, the fast-growing Internet of Things meant that programs now had to run on a coffee machine in a sense that was no longer metaphorical. In some places, development speed was missing. In others, safety was.<br><br>We escaped from assembly into C, from C into managed runtimes, from ceremonial enterprise Java into Kotlin, from dynamic-language freedom into TypeScript, from unsafe systems code into Rust, and from heavy frameworks into smaller cloud-native tools. At first glance, all migration channels seem clear. But how does this map onto reality?<br>Quite a lot of material, in one way or another, measures how the popularity of programming languages changes over time. Yet it seems that no one has really looked at the broader picture of how programmers themselves move between languages – not from the point of view of global trends in software development, but from the point of view of an individual path.<br><br>For us at JetBrains, it is very important to get closer to understanding what is happening from the programmer’s perspective, rather than from that of a programming historian or a career adviser. This is the perspective that matters most to us. In this spirit, we designed our State of Developer Ecosystem surveys with the goal of illuminating what the path of a real programmer looks like. Here’s what we found in 2025.<br>First, we should acknowledge that the path between languages can look like almost anything. Yes, the most common routes are between the leading languages: from Python to Java and back, with Java to Kotlin in third place by absolute numbers. But people migrate in every possible direction.<br><br>But we’ve gotten ahead of ourselves. Let’s take things one step at a time.</p>



<h3 class="wp-block-heading"><strong>What we did before and what we achieved in 2025</strong></h3>



<p>Since the beginning of the Development Ecosystem survey, we have used the question <em>“Do you plan to adopt or migrate to other languages in the next 12 months? If so, which ones?”</em> We quickly found, however, that it is not a good predictor for future language migration. It’s one thing to plan to try Rust or switch from Java to Kotlin, but even for very common moves, the number of developers who actually make the switch is much lower than the number of those who have plans. Just because we have issues supporting our old Java 8 codebase, for example, doesn’t mean we’ll actually leave it.<br>So last year, we added a new set of questions regarding respondents’ previous experience with programming languages. We decided to assess actual migration over the past year using the question <em>“What were your primary programming languages 12 months ago?”</em> and some other related ones. This report addresses these questions, as well as the programming language landscape as a whole, based on the 8,837 responses we collected.<br>For reference, the following terms refer to the answers of the corresponding questions:<br>Used language – “<em>Which programming languages have you used in the last 12 months?</em>”<br>Primary language – “<em>What are your primary programming languages? (Up to 3)”</em><br>Main language – <em>“What is your main programming language?”</em></p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/pl_dynamics_2017_2025.png" alt="" class="wp-image-729330" /></figure>



<p>This сhart is based on the responses to the question “Which programming languages have you used in the last 12 months?” The increase in Java and Kotlin shares is most likely the result of a shift in the sample, rather than a real trend. The main fast risers are TypeScript and Rust, as we described in our <a href="https://www.jetbrains.com/lp/devecosystem-2024/#language_promise_index" target="_blank" rel="noopener">2024 Developer Ecosystem infographic</a>. We also predicted some growth for Python, Go, and Lua, but only Go showed actual growth.</p>



<h3 class="wp-block-heading"><strong>JetBrains Language Promise Index</strong></h3>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/language_promise_index.png" alt="" class="wp-image-729342" /></figure>



<p>The Language Promise Index tracks the migration prospects of languages in arbitrary units, based on the data we had on the stability of positive or negative migration dynamics and the number of people wishing to learn the language. <strong>Lua </strong>was previously one of the top languages in this category, but its growth has apparently reached a certain ceiling, and it is no longer among the leaders.</p>



<p>TypeScript, Rust, Python, and Go all still have large growth potential. We expect that a lot of people would change their main language from JavaScript to TypeScript while still using JS as their secondary language.&nbsp;</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/lang_usage_breakdown.png" alt="" class="wp-image-729354" /></figure>



<p>As you can see, despite being the most popular language in terms of overall usage, JavaScript is the main language for only 6% of software developers, while Java is still much more popular as a main language.&nbsp;</p>



<p>Unfortunately, we don’t have enough answers for most programming languages, so the next tables include only the most popular ones.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/lang_net_growth_composition.png" alt="" class="wp-image-729365" /><figcaption class="wp-element-caption"><em>100% represents all respondents who reported using the respective language as their main language one year ago. </em><br><em>Loyals + Churners = 100%. <br>Net Growth = Newcomers + Switchers – Churners.<br>Newcomers – respondents who did not use any programming language one year ago but reported using this language this year.</em><br><em>Switchers – respondents who used a different main language one year ago and switched to this one.</em><br><em>Loyals – respondents who continued using the same main language as last year.</em><br><em>Churners – respondents who used this language as their main language a year ago but have since switched to another language.</em><br></figcaption></figure>



<p>Surprisingly, C shows the lowest retention. About half of those who said that C was their main language last year have now switched to something else. This is a bit strange. Initially, we assumed that this flow probably consisted of students who had adopted C through their education and then switched to another language. However, the experience level has only a small effect. Half of those who dropped C chose <em>“I wanted to learn a new language”</em> as the reason for their change, which has a higher share than among switchers from other languages, who mostly chose <em>“A project I am working on requires the usage of a new language.”</em><br>However, we didn’t have such questions for last year and do not see so much churn for C based on a comparison of shares with previous-year data (2.1% this year as a main language vs 2.0% in last year). But this churn rate may be a good predictor of future changes.</p>



<h3 class="wp-block-heading">Why developers leave – and where they go</h3>



<p>First of all, we should say that we don&#8217;t have data about everyone who churned – people who retired or switched to another career path don’t typically answer our developer surveys. Nevertheless, we do have enough information to draw some conclusions about why people decide to switch from one language to another.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/churn_reasons_by_from_lang_heatmap.png" alt="" class="wp-image-729376" /></figure>



<p>Note: The sample is extremely small (less than 100) for C, Kotlin, and PHP.,<br>Some findings from this data:<br>1. Project requirements are the most common reasons for switching languages.<br>2. As we mentioned before, for C, <em>“I wanted to learn a new language”</em> and <em>“More modern language features”</em> are very popular reasons for switching, which probably point to widespread dissatisfaction and the language’s aging.<br>3. For JavaScript, the reason people leave is often <em>“Better job market opportunities”.</em><br>4. Performance and scalability limitations are often a reason to switch from PHP.<br>5. “Other” reasons accounted for 18% of Kotlin churners. According to their answers, they are switching companies and switching between hobby and professional use.</p>



<p>The following tables, where both rows and columns list the same programming languages, require some additional explanation. Each one depicts the shift in respondents’ main languages. In the first, the columns are divided by last year’s responses for a given language, and the rows show the languages that respondents have moved to. Conversely, the second tracks where new language users are coming from, with the columns divided by respondents’ current main languages and the rows showing their previous answers. Each column totals 100%, because it tracks the same population over the course of a year.&nbsp;</p>



<p>The tables show transitions from seeing one language as your “main” language to seeing another language that way. This does not mean that people stopped programming in the “abandoned” language altogether. It simply means that it stopped being their primary language.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/churn_destinations_heatmap.png" alt="" class="wp-image-729387" /></figure>



<p>This table shows where people go based on their previous language. Python is the main switch destination for all languages except C (whose users preferred to move to Java and C++) and TypeScript (where the top target destinations were Java, JavaScript, and C#).<br></p>



<h3 class="wp-block-heading">Why developers adopt – and where they come from</h3>



<p>Let’s look at the inverted perspective, based on the language to which people migrated.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/join_reasons_by_to_lang_heatmap.png" alt="" class="wp-image-729546" /></figure>



<p>Some findings from this data:</p>



<ol class="wp-block-list">
<li>Surprisingly, JavaScript is both the main language people leave for better job market opportunities and the one people move to for the same reason. But these flows are not the same: one of the main sources for JavaScript growth is HTML/CSS. So, the pattern looks a bit like a conveyor belt: HTML to JavaScript to TypeScript.&nbsp;</li>



<li>Project requirements are very common reasons for switching to C# and C++, suggesting many developers switch to these languages simply because they have to.&nbsp;</li>



<li>People don’t go to Kotlin because they have to, but because it offers a better development experience and more modern language features.</li>



<li>Performance and scalability are the main attractions of Go, whereas ecosystem and library support are stronger attractions for Python.</li>
</ol>



<p>At first glance, the following table may look the same as the main-language churn table above. But it is actually completely different, with a different meaning.</p>



<p>Here, the language that respondents see as their main language at the time of answering is taken as 100%. Accordingly, the diagonal shows what we called the continuity rate: the share of people who use this language as their main language now and also used it as their main language a year ago. Imagine that we have 150 respondents. Of them, 100 said they use a certain language as their main language this year, while 125 said they used it as their main language last year. 75 people used this language as their main language both a year ago and at the time of the survey.</p>



<p>In this case, the retention rate would be 75%, while the continuity rate would be 60%. It is important to note that everyone else is not necessarily a “newcomer” to the language. They may well have used this language before, just not as their main one.</p>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/08/growth_sources_heatmap.png" alt="" class="wp-image-729760" /></figure>



<p>In terms of growth sources, Python is the main source for C, C#, C++, Go, Java, and JavaScript, which is not surprising, because it is one of the most popular languages.</p>



<p>For Kotlin, the main growth source is Java, while for PHP and TypeScript, it is JavaScript.</p>



<p>For Python itself, the main growth source is Java.&nbsp;</p>



<h3 class="wp-block-heading">Conclusion</h3>



<p>By looking at actual moves instead of plans, we shift from intention to action – not what developers say, but what they do. The ecosystem data stops being a snapshot and starts to look like a map of flows.</p>



<p>Project requirements still do most of the pushing. Necessity, not choice, drives many switches, but not all. Some languages win on specific jobs, others on performance or ecosystem. And many developers move in chains: from HTML/CSS to JavaScript, and then further along – a conveyor belt of skills, where each step opens the next.</p>



<p>Churn tells a clearer story. C leaks talent faster than expected, even if its headline numbers look stable. Java remains a hub, but its outflow goes mostly to Python and TypeScript, not Kotlin. Python acts as a catch-all destination. TypeScript and Rust still look like the forward edge.</p>



<p>Kotlin, our own language, plays a different game – and plays it well. Developers come not because they have to, but because they want to, drawn by cleaner syntax, fewer rough edges, and a development experience that simply feels better. It wins on pull, not push. Yet the inflow from Java is weaker than expected, and some developers even switch back.<br><br>The picture that emerges is a simple one of push, pull, and drift. With the new data, we see not just which languages grow or shrink, but how it happens – which languages move with the current, and which have to work against it.</p>



<p>Let’s see what DevEco’26 will reveal.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Kodee’s Kotlin Roundup: Birthday Wishes, Shipaton 2026, and the New Kotlin AI Benchmark</title>
		<link>https://blog.jetbrains.com/kotlin/2026/08/kodees-kotlin-roundup-birthday-wishes-shipaton-2026-and-the-new-kotlin-ai-benchmark/</link>
		
		<dc:creator><![CDATA[Kodee]]></dc:creator>
		<pubDate>Tue, 04 Aug 2026 08:14:27 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/07/KT-social-BlogFeatured-1280x720-1-5.png</featuredImage>		<category><![CDATA[kotlin]]></category>
		<category><![CDATA[news]]></category>
		<category><![CDATA[kotlin-roundup]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=727205</guid>

					<description><![CDATA[Hi everyone! July gave me plenty to celebrate: Kotlin turned 15, got its first public benchmark for AI coding agents, became available in BlueJ, and shipped its 2.4.10 release. Developers can also demonstrate their skills at RevenueCat Shipaton 2026 by building a Kotlin Multiplatform app and competing for the Ship Kotlin Everywhere Award. Meanwhile, X [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Hi everyone! July gave me plenty to celebrate: Kotlin turned 15, got its first public benchmark for AI coding agents, became available in BlueJ, and shipped its 2.4.10 release. Developers can also demonstrate their skills at RevenueCat Shipaton 2026 by building a Kotlin Multiplatform app and competing for the Ship Kotlin Everywhere Award. Meanwhile, X has rebuilt its Android app to be 100% Kotlin, marking another milestone for the language.</p>



<p>Here’s what stood out to me most over the past month:</p>


            <div class="newsletter">
                            <h2>Kodee-approved spotlight</h2>
                                                            <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/Kotlin-Release-X-LinkedIn-FB-Bluesky-1200x675-1-4.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>Kotlin turned 15: Leave a birthday wish</h3>
                                                        <p>This one is close to my heart – Kotlin recently turned 15! To mark the milestone, we&#8217;re inviting the whole community to celebrate. You can create a birthday postcard, upload a photo to party with me, and share a wish or a prediction for Kotlin&#8217;s next chapter. Now is the perfect moment to look back at how far we&#8217;ve come – and to look ahead together.</p>
                                                            <a href="https://kotlinlang.org/kotlin-effect/" class="btn" target="_blank" rel="noopener">Join the celebration</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/Kotlin-Release-X-LinkedIn-FB-Bluesky-1200x675-1-3.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>Ship Kotlin Everywhere Award at RevenueCat Shipaton 2026</h3>
                                                        <p>Already know Kotlin? RevenueCat Shipaton 2026 is the perfect opportunity to turn your Kotlin skills into a new app. From August 1 to September 30, build and ship for Android, iOS, desktop, or web and compete for the Ship Kotlin Everywhere Award. Use the <a href="https://kotlinlang.org/docs/multiplatform/shipathon-starter-guide.html" target="_blank" rel="noopener">KMP starter guide</a> to get your project up and running. To earn bonus points, you can help others by sharing your development journey. Shipping is impressive, but helping someone else is even better.</p>
                                                            <a href="https://kotlinlang.org/lp/shipaton/" class="btn" target="_blank" rel="noopener">Learn more and register</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/KT-social-BlogFeatured-1280x720-1.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>The Kotlin Benchmark for AI coding agents</h3>
                                                        <p>Kotlin now has its very own public benchmark for AI coding agents. It ranks agents on 105 real engineering tasks drawn from open-source Kotlin repositories, so you can compare them by resolution rate, token cost, and latency – and dig into the methodology behind the numbers. As AI becomes a bigger part of coding in Kotlin, I love that we finally have an open, Kotlin-specific way to measure what actually works.</p>
                                                            <a href="https://blog.jetbrains.com/kotlin/2026/07/introducing-the-kotlin-benchmark-evaluate-ai-coding-agents-on-real-world-kotlin-tasks/" class="btn" target="_blank">Explore the benchmark</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/04/KT-social-BlogFeatured-1280x720-1-2.png" alt="Kotlin release updates">
                                                                            <div class="newsletter__post-text">
                                                            <h3>Kotlin 2.4.10 and Kotlin 2.4.20-Beta2</h3>
                                                        <p>July brought the Kotlin 2.4.10 bug fix release, alongside Kotlin <a href="https://kotlinlang.org/docs/whatsnew-eap.html" target="_blank" rel="noopener">Kotlin 2.4.20-Beta2</a> with coroutine stack trace recovery, faster klib compilation, expanded Swift export, and an experimental compiler native image. Try the Beta version and share your feedback while the release is still taking shape.</p>
                                                            <a href="https://github.com/JetBrains/kotlin/releases/tag/v2.4.10" class="btn" target="_blank" rel="noopener">See the Kotlin 2.4.10 changelog</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/06/Kotlin-Release-Blog-Featured-Blog-1280x720-1.png" alt="Kotlin Comes to BlueJ">
                                                                            <div class="newsletter__post-text">
                                                            <h3>Kotlin comes to BlueJ</h3>
                                                        <p>Kotlin support is now available in BlueJ 6.0 thanks to a collaboration between JetBrains and the BlueJ team at King’s College London. Students can create, edit, compile, and run Kotlin code, inspect class diagrams, and interact with objects through BlueJ’s familiar workflow. For educators, a new onboarding guide and ready-to-use materials make it easier to include Kotlin’s concise syntax and null safety in introductory object-oriented programming courses.</p>
                                                            <a href="https://blog.jetbrains.com/kotlin/2026/07/kotlin-comes-to-bluej/" class="btn" target="_blank">Read the post</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/Blog-Featured-Blog-1280x720-1.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>A conversation with the Golden Kodee winners</h3>
                                                        <p>The first Golden Kodee Community Awards recognized Matheus Leandro Ferreira, Jaewoong Eum, Nicole Terc, Eeva-Jonna Panula, and Yinlong Liu for their contributions to education, online presence, creativity, positive societal impact, and in-person community building. Read their interviews and <a href="https://www.youtube.com/watch?v=p88y4pjb8Cg" target="_blank" rel="noopener">watch the video</a> to discover practical advice on learning in public, starting small, and helping the community grow.</p>
                                                            <a href="https://blog.jetbrains.com/kotlin/2026/07/in-conversation-with-the-golden-kodee-winners/" class="btn" target="_blank">Meet the Golden Kodee winners</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/06/Blog-Featured-1280x720-4.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>Showcase your JetBrains IDE experience on LinkedIn</h3>
                                                        <p>The free LinkedIn Connected Apps plugin lets you connect a supported JetBrains IDE to your LinkedIn profile. Once connected, a profile statement highlights how you use your IDE in practice, based on usage data that stays on your machine. As your development habits evolve, the statement updates automatically to reflect your experience. It is designed to showcase practical tool usage – not to rank developers or replace formal certification.</p>
                                                            <a href="https://plugins.jetbrains.com/plugin/32011-linkedin-connected-apps" class="btn" target="_blank" rel="noopener">Connect your IDE to LinkedIn</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/Blog-Featured-1280x720-1.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>How I came to life</h3>
                                                        <p>I didn’t always look like this! My journey began with a simple robot-inspired concept. Then, with the help of research, creativity, and community feedback, I evolved into the Kodee you know and love today. Check out my origin story (including how I got my name!).</p>
                                                            <a href="https://blog.jetbrains.com/research/2026/07/the-history-of-kodee/" class="btn" target="_blank">Discover the story behind Kodee</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/klibsionew.jpg" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>KMP library spotlight: Ktor, Koin, and Kermit</h3>
                                                        <p>Finding the right KMP library shouldn’t slow down your project. klibs.io brings together more than 4,100 Kotlin Multiplatform libraries, with filters for developers and <a href="https://klibs.io/ai" target="_blank" rel="noopener">AI integrations</a> that give coding agents access to accurate, up-to-date library data. This month, we’re spotlighting <a href="https://klibs.io/project/ktorio/ktor" target="_blank" rel="noopener">Ktor</a>, <a href="https://klibs.io/project/InsertKoinIO/koin" target="_blank" rel="noopener">Koin</a>, and <a href="https://klibs.io/project/touchlab/Kermit" target="_blank" rel="noopener">Kermit</a> – a practical trio for networking, dependency injection, and logging.</p>
                                                            <a href="https://klibs.io/" class="btn" target="_blank" rel="noopener">Find your next KMP library</a>
                                                    </div>
                    </article>
                                    <article class="newsletter__post">
                                                                                    <img style="width:100% !important; height:auto !important; max-width:100% !important;" decoding="async" class="newsletter__post-img" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/androidxapp.png" alt="">
                                                                            <div class="newsletter__post-text">
                                                            <h3>X rebuilds its Android app in 100% Kotlin</h3>
                                                        <p>Built from scratch, X’s Android app is now written entirely in Kotlin. X Chat also uses Kotlin Multiplatform across Android, iOS, and web for end-to-end encryption, storage, sync, and business logic. It’s exciting to see Kotlin and Kotlin Multiplatform used at this scale.</p>
                                                            <a href="https://x.com/kotlin/status/2079882056465535142" class="btn" target="_blank">Check out the rebuilt app</a>
                                                    </div>
                    </article>
                                    </div>
    


<h2 class="wp-block-heading">Where you can learn more</h2>



<ul class="wp-block-list">
<li><a href="https://kotlinlang.org/docs/multiplatform/compose-navigation-3.html" target="_blank" rel="noreferrer noopener">Learn how to use Navigation 3 in Compose Multiplatform</a>.</li>



<li><a href="https://kotlinlang.org/docs/multiplatform/multiplatform-cocoapods-spm-migration-ai.html" target="_blank" rel="noreferrer noopener">Move a KMP project from CocoaPods to SwiftPM dependencies with help from Junie</a>.</li>



<li><a href="https://klibs.io/ai" target="_blank" rel="noreferrer noopener">Connect your AI coding agent to klibs.io for up-to-date KMP library data</a>.</li>



<li><a href="https://kotlinlang.org/docs/kotlin-ai-skills.html" target="_blank" rel="noreferrer noopener">Use Kotlin AI skills for common migration tasks</a>.</li>



<li><a href="https://blog.jetbrains.com/research/2026/07/kotlinllm-open-source/" target="_blank" rel="noreferrer noopener">KotlinLLM is Going Open Source</a>.</li>



<li><a href="https://blog.jetbrains.com/kotlin/2026/07/secure-your-apis-oauth2-and-jwt-for-beginners/" target="_blank" rel="noreferrer noopener">Learn how to secure APIs built with Kotlin and Spring Boot using OAuth2 and JWT</a>.</li>



<li><a href="https://kotlinlang.org/docs/spring-boot-claude.html" target="_blank" rel="noreferrer noopener">Build a task manager app with Kotlin, Spring Boot, and Claude Agent</a>.</li>



<li><a href="https://kotlinlang.org/education/" target="_blank" rel="noreferrer noopener">Explore Backend Development with Kotlin – presentation slides and a runnable demo project</a>.</li>



<li><a href="https://spring.io/blog/2026/07/02/a-bootiful-podcast-sebastien-deleuze" target="_blank" rel="noreferrer noopener">Listen to Sébastien Deleuze and Josh Long talk Kotlin for backend on<em> A Bootiful Podcast</em></a>.</li>
</ul>



<h2 class="wp-block-heading">YouTube highlights</h2>



<ul class="wp-block-list">
<li><a href="https://www.youtube.com/watch?v=VVf6txPZk3Y" target="_blank" rel="noreferrer noopener">Sony’s KMP Journey: Scaling BLE &amp; Hardware with Kotlin Multiplatform | Sergio Carrilho</a>.</li>



<li><a href="https://www.youtube.com/watch?v=djrt5zsATtM" target="_blank" rel="noreferrer noopener">What’s New in Compose Multiplatform | Sebastian Aigner and Márton Braun</a>.</li>



<li><a href="https://www.youtube.com/watch?v=-w97euRLTBA" target="_blank" rel="noreferrer noopener">Run, Kotlin, Run! | Marc Reichelt</a>.</li>



<li><a href="https://www.youtube.com/watch?v=25Ngfn9Bhqc" target="_blank" rel="noreferrer noopener">A First Look at the Kotlin Ecosystem Plugin for Declarative Gradle | Marcin Mycek</a>.</li>



<li><a href="https://www.youtube.com/watch?v=9XL0r5lJNDs" target="_blank" rel="noreferrer noopener">Building Enterprise Ready AI With Koog | Vadim Briliantov</a>.</li>



<li><a href="https://www.youtube.com/watch?v=1sp05VqRVDA" target="_blank" rel="noreferrer noopener">Real-World Data Science With Kotlin Notebook | Adele Carpenter</a>.</li>



<li><a href="https://www.youtube.com/watch?v=5ccWWM3AZBU" target="_blank" rel="noreferrer noopener">Evolving Kotlin Language Defaults | Michail Zarečenskij</a>.</li>



<li><a href="https://www.youtube.com/watch?v=O1nTwf0QPj4" target="_blank" rel="noreferrer noopener">Context Parameters and API Design | Alejandro Serrano Mena</a>.</li>



<li><a href="https://www.youtube.com/watch?v=xGZIH-hfyhI" target="_blank" rel="noreferrer noopener">Concurrency Patterns for Modern High-Performance Kotlin Servers | Bowen Feng</a>.</li>



<li><a href="https://www.youtube.com/watch?v=dmOrYzS_AKM" target="_blank" rel="noreferrer noopener">Deconstructing OkHttp | Jesse Wilson</a>.</li>
</ul>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Know Kotlin? Ship It Everywhere and Win at Shipaton 2026</title>
		<link>https://blog.jetbrains.com/kotlin/2026/07/know-kotlin-ship-it-everywhere-and-win-at-shipaton-2026/</link>
		
		<dc:creator><![CDATA[Ekaterina Petrova]]></dc:creator>
		<pubDate>Fri, 31 Jul 2026 13:49:33 +0000</pubDate>
		<featuredImage>https://blog.jetbrains.com/wp-content/uploads/2026/07/KT-social-BlogFeatured-1280x720-1-6.png</featuredImage>		<category><![CDATA[multiplatform]]></category>
		<category><![CDATA[news]]></category>
		<guid isPermaLink="false">https://blog.jetbrains.com/?post_type=kotlin&#038;p=727590</guid>

					<description><![CDATA[Somewhere in your notes there&#8217;s an app idea waiting for a free weekend that never comes. Consider this its official deadline: RevenueCat Shipaton 2026, the world&#8217;s biggest mobile hackathon, runs August 1 to September 30. If you know Kotlin, that idea is closer to the App Store than you think. Join the Shipaton The Ship [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Somewhere in your notes there&#8217;s an app idea waiting for a free weekend that never comes. Consider this its official deadline: <a href="https://kotlinlang.org/lp/shipaton/?utm_source=kotlin-blog&amp;utm_medium=blog&amp;utm_campaign=shipaton2026" target="_blank" rel="noopener">RevenueCat Shipaton 2026</a>, the world&#8217;s biggest mobile hackathon, runs August 1 to September 30.</p>



<p>If you know Kotlin, that idea is closer to the App Store than you think.</p>



<p align="center"><a class="ek-link jb-download-button" title="Join the Shipaton" href="https://kotlinlang.org/lp/shipaton/?utm_source=kotlin-blog&#038;utm_medium=blog&#038;utm_campaign=shipaton2026" target="_blank" rel="noopener">Join the Shipaton</a></p>



<h2 class="wp-block-heading">The Ship Kotlin Everywhere Award</h2>



<p>JetBrains is a Gold Sponsor of Shipaton this year, with our own category. The idea is simple: reuse the Kotlin you already know to build one brand-new app and bring it to multiple platforms, including Android, iOS, desktop, and web, with <a href="https://kotlinlang.org/multiplatform/" target="_blank" rel="noopener">Kotlin Multiplatform</a> and <a href="https://kotlinlang.org/compose-multiplatform/" target="_blank" rel="noopener">Compose Multiplatform</a>.</p>



<p>You don&#8217;t need to hit all four platforms. Judges reward effective cross-platform development, not platform count alone.</p>



<h2 class="wp-block-heading">What you can win</h2>



<p>The award has a $30,000 prize pool split among three winners: $15,000, $10,000, and $5,000. The first-place app also receives Shipaton’s first-place category winner package: a feature on a Times Square billboard, an invitation to RevenueCat’s App Growth Annual conference in New York City on October 21, a custom Shippy trophy, and a media spotlight.</p>



<p>One more thing: you submit once and compete everywhere. Your Kotlin Multiplatform app also stays in the running for the <strong>$100,000 Grand Prize</strong> and more than 20 other categories, from #BuildInPublic to the Best Game Award, with over $1,000,000 worth of prizes in total.</p>



<p>Don&#8217;t just take our word for it. Here&#8217;s Chris Krueger, whose app <a href="https://devpost.com/software/momental" target="_blank" rel="noopener">Momental</a> took first place in our KMP category at Shipaton 2025:</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow">
<p><em>&#8220;Building Momental with Kotlin Multiplatform was very enjoyable. Sharing one codebase for Android and iOS gave me so much more time to focus on user feedback and actually improving the app. I was amazed how quickly I could build a beautiful, complex UI — even features like a full music player with soundscapes worked smoothly across platforms.</em></p>



<p><em>If you&#8217;re hesitating, just enter the challenge. It forces you to grow, explore new parts of KMP, and ship faster than you expect. You&#8217;ll reach way more users than you think possible.&#8221;</em></p>
</blockquote>



<figure class="wp-block-image size-full"><img style="width:100% !important; height:auto !important; max-width:100% !important;" loading="lazy" decoding="async" src="https://blog.jetbrains.com/wp-content/uploads/2026/07/image-55.png" alt="" class="wp-image-727602"/><figcaption class="wp-element-caption">Chris Krueger with his award and Momental in Times Square.</figcaption></figure>



<h2 class="wp-block-heading">What you get as a participant</h2>



<ul class="wp-block-list">
<li><strong>IntelliJ IDEA Ultimate, free for 3 months</strong> for the first 1,000 builders</li>



<li><strong>Access to Junie</strong>, our AI coding agent, for 2 months for 200 builders ready to build in public</li>



<li>A Starter Guide, an AI Guide, weekly livestreams, and JetBrains advocates answering questions in Discord</li>
</ul>



<h2 class="wp-block-heading">Ready to ship?</h2>



<p>Everything you need is on the award page: rules, the starter kit, offers, and the timeline.</p>



<p align="center"><a class="ek-link jb-download-button" title="Join the Ship Kotlin Everywhere Award" href="https://kotlinlang.org/lp/shipaton/?utm_source=kotlin-blog&#038;utm_medium=blog&#038;utm_campaign=shipaton2026" target="_blank" rel="noopener">Join the Ship Kotlin Everywhere Award</a></p>



<p>Happy shipping!</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
