
Kotlin 2.4.0 is out as a stable release, and the headliner is context parameters finally graduating from years of experimental status to Stable. You no longer need an opt-in compiler flag. You can ship them in production code today without worrying about surprise breakage in the next release. But 2.4.0 also ships incremental Wasm builds on by default, Swift Package Manager support in KMP, explicit backing fields promoted to Stable, and a formal 18-month security support window for the JVM standard library. There is a lot to unpack.
Context Parameters Are Now Stable
Context parameters let functions and properties declare dependencies that are resolved implicitly from the surrounding call context — without passing them as explicit arguments down every layer of your stack. They have been in experimental or preview status across multiple Kotlin releases. In 2.4.0, they graduate to Stable for most usage. No opt-in flag. No migration warning. Just ship it.
The practical win is significant. If you have ever threaded an auth context, a database transaction handle, or a tenant ID through five layers of functions just so the innermost function could read it, context parameters are the fix. Here is a before/after:
// Before: every function in the chain receives deps it may not even use
fun saveOrder(order: Order, auth: AuthContext, db: DatabaseContext) {
validateOrder(order, auth, db)
}
// After: context parameters propagate implicitly through the call chain
context(auth: AuthContext, db: DatabaseContext)
fun saveOrder(order: Order) {
validateOrder(order) // auth and db are in context, no explicit pass
}
The compiler injects context as the first argument at compile time — zero runtime overhead compared to a regular function call. Context parameters work correctly with coroutines: context(tx: DatabaseTransaction) suspend fun is valid. And unlike ThreadLocal-based patterns, they work on iOS and JS targets in Kotlin Multiplatform, because there is no ThreadLocal to break.
One new addition in 2.4.0: explicit context arguments. When two overloads differ only by context parameters and a call becomes ambiguous, you can now pass a context explicitly at the call site to resolve it. Callable references and explicit context arguments are still under an experimental flag, but the core feature is stable.
If your team has been holding off on adopting context parameters in API design, the wait is over. This is the most impactful language change Kotlin has shipped in years.
Kotlin/Wasm Builds Are Fast Now
Incremental compilation in Kotlin/Wasm is now Stable and enabled by default. Previously, any change in a Wasm target triggered a full recompile. Now only the affected files rebuild. JetBrains says this doubles development speed, with further improvements planned. If you have been holding off on Kotlin for browser or edge work because of rebuild times, that excuse is gone.
2.4.0 also adds WebAssembly Component Model support. This is the spec that turns Wasm from a compile target into a composable component system. Kotlin/Wasm modules can now be composed with Rust, Go, or C++ Wasm modules using standardized WIT interfaces. WASI 0.2 is built on this model. Kotlin is no longer just a Wasm consumer — it is a participant in the broader composable Wasm ecosystem.
KMP iOS Just Got Less Painful
Two changes in 2.4.0 make Kotlin Multiplatform on iOS meaningfully better. Swift packages are now directly importable as KMP module dependencies using the swiftPMDependencies {} block in your Gradle config. SPM is built into Xcode, so no extra tooling is required — no more wrapping Swift-only iOS SDKs in Objective-C headers to get them into a KMP module.
The CMS (Concurrent Mark and Sweep) garbage collector is also now the default in Kotlin/Native. It was experimental since 2.0.20. The concurrent marking phase runs alongside app threads, reducing GC pause duration on iOS. KMP apps feel smoother as a result.
Explicit Backing Fields: Clean Up Your ViewModels
Explicit backing fields are stable in 2.4.0. Every Android developer writing Jetpack Compose or StateFlow knows the pattern — one private mutable property and one public read-only property for the same piece of state. Two declarations, one concept. The new syntax collapses this into one:
// Before: the standard Compose/Flow boilerplate
private val _uiState = MutableStateFlow(UiState())
val uiState: StateFlow<UiState> = _uiState
// After: explicit backing field syntax
val uiState: StateFlow<UiState> field = MutableStateFlow(UiState())
This is a small change in terms of spec scope but it removes a persistent paper cut from Android architecture code. Go update your ViewModels.
The 18-Month stdlib Security SLA Is an Enterprise Signal
Starting with Kotlin 2.4.0, each release line of the JVM kotlin-stdlib gets an 18-month security support window. Security fixes will be backported to all active release lines and released as patch versions. The scope is the JVM kotlin-stdlib runtime artifact.
This matters for the enterprise JVM market. Banks, telecoms, and large product teams with slow upgrade cycles need to know how long a release line is supported before committing to it. Kotlin is now making the same kind of formal commitment that JDK LTS releases do. It is an acknowledgement that Kotlin is serious infrastructure, not just a hip JVM language.
Should You Upgrade?
Yes, for most teams. A few notes before you do:
- Android and Spring Boot: Upgrade now. Context parameters stable plus explicit backing fields means immediate code quality improvements with no breaking changes.
- KMP with iOS targets: Upgrade for CMS GC default behavior and Swift package imports. The iOS experience is noticeably better.
- Kotlin 1.9 users: 2.4.0 drops support for
-language-version=1.9and removes the K1 compiler. You will need to migrate through the 2.x line before reaching 2.4. - Wasm projects: Incremental compilation alone justifies the upgrade.
Other additions worth knowing: Java 26 is now a supported JVM target, Gradle 9.5.0 is the max fully-supported version, the common UUID API is stable across all Kotlin targets, and Kotlin/JS gains value class export and ES2015 inlining improvements. Full release notes are at the JetBrains Kotlin blog and the official what’s new page.













