JetBrains is testing two new mechanisms in Kotlin 2.5.0 called Companion Blocks and Companion Extensions, aiming to expand how type-associated members are defined and improve interoperability across different Kotlin platforms. The company says the new design enables programming patterns that were not easily available using traditional Companion Objects.
What does the new mechanism add?
Type-associated members are used to define constants, utilities, and factory functions that do not belong to a single object, such as a constant representing the zero vector or a function that creates a vector according to a specific angle. Previously, this use case relied on Companion Objects, whereas the new companion blocks allow this type of member to be written in a form closer to defining it inside the type itself.
Companion Extensions, meanwhile, allow associated members to be added to any class or interface, even when the developer does not own the original code, and even if the type comes from Java or does not originally contain a Companion Object. This means external types can be extended without modifying their basic definition.
Changes to compilation and compatibility
The new mechanism differs from Companion Objects in its compilation strategy. On the JVM platform, Companion Blocks are compiled into static members, bringing their behavior closer to static members on other platforms. JetBrains believes this may benefit Kotlin Multiplatform, as expected members can be defined in a companion block and then implemented using a Java class containing static members.
However, the features are still experimental. Enabling Companion Blocks requires the -Xcompanion-blocks option, while combining blocks and extensions requires the -Xcompanion-blocks-and-extensions option.
Limitations of experimental use
When Companion Extensions are used, the compiler produces pre-release binary files. Accordingly, other projects or libraries may not be able to consume libraries that use these extensions as dependencies until the feature officially stabilizes. The same limitation does not apply to exposing Companion Blocks, but their users will also need to enable the feature.
Should Companion Objects be migrated?
JetBrains does not recommend an immediate migration. Companion Objects remain a fundamental part of Kotlin, and full support for them is guaranteed. Companion Blocks may be the preferred option for new code in most cases, but Companion Objects remain necessary in certain situations, such as when the companion needs to implement an interface, because they are compiled into a complete class.
In practice, in many cases it may be enough to remove the word object to switch to a Companion Block, but the project and all code that depends on it will need to be recompiled. JetBrains also warns that some ecosystem tools may not yet be ready to handle the new syntax.
Why does this development matter?
The change is important for Kotlin Multiplatform developers and library authors because it attempts to narrow the gap between the concept of static members on the JVM and on other platforms. However, its practical value currently remains tied to an experimental phase and to how quickly build tools, libraries, and editors are updated. Therefore, Companion Blocks appear suitable for experimentation and design evaluation, rather than as a safe foundation for broad migration before the feature stabilizes.