KComp provides convenient string literal processing for working with Minecraft chat components.
Components are Minecraft's way of allowing formatted text in chat (and various other places). They are serialized as JSON and support nesting via each component's children
tag.
On top of Minecraft's implementation of components (which is closed source), there are other implementations, such as the Bungee one, and the more modern and now widely used kyori-adventure.
While these implementations are powerful and allow working with components in a type-safe way, they make composing components much more tedious.
Consider the following example:
val input = Component.text("UltraDev") val welcomeMessage = Component.text("Welcome, ").append(input).append(Component.text("!"))
The code can be made slightly better by either statically importing Component.text
or using kotlin's extension functions for converting strings
val input = "UltraDev".toComp() val welcomeMessage = "Welcome, ".toComp().append(input).append("!".toComp())
but the main issue is still composing components.
Kyori's MiniMessage (also part of the adventure project) makes this somewhat easier by providing a way of using string formats
val input = "UltraDev".toComp() val welcomeMessage = MiniMessage.miniMessage().deserialize("Welcome, <input>!", Placeholder.component("input", input))
Placeholders are nice, but require writing lots of repetitive code, instead I wanted something nicer, I wanted to be able to write
val input = "UltraDev".toComp() val welcomeMessage = "Welcome, ${input}!".toComp()
Unfortunately, Kotlin does not currently support custom string interpolation like Scala, so we need to use a compiler plugin instead.
The Kotlin compiler is largely undocumented, and writing a plugin requires working with the intermediate representation (IR) used by the compiler.
The KCompTransformer
class handles transforming the IR and replacing string interpolations in calls to toComp with a set of placeholders.
Unfortunately, working directly with the IR has its downsides, and during the initial usage of KComp I ran into countless bugs and edge cases.
Overall, I learned a lot about the Kotlin compiler and ended up with a useful library. Nevertheless, the library is not perfect, and if I was to do this again, I would use an existing compiler plugin such as Terpal.
Created: 7/16/2025
Last updated: 7/17/2025