TOON (Token-Oriented Object Notation) is a lightweight, human-friendly data serialization format designed for concise, structured data — ideal for LLMs, configuration files, structured logs, and beyond.
kotlin-toon is a 100% Kotlin implementation — spec-compliant and ready for production. Based on the original spec from Johann Schopplich:
TOON is inspired by the readability of YAML and the tabular elegance of CSV, and specially useful to provide structured data for LLM APIs (because a verbose protocol generates more tokens, and tokens can be expensive).
| Feature | Description |
|---|---|
| ✅ Indentation-based hierarchy | Uses spaces to define structure (like YAML) |
| ✅ Table syntax | users[3]{id,name} for compact tabular records |
| ✅ Fully typed API | Converts directly into Kotlin data classes (soon) |
| ✅ No dependencies | Pure Kotlin, zero external libraries |
| ✅ Reversible encoding | decode → encode → decode is lossless |
| ✅ Performance-optimized | Fast, linear parsing — ideal for JVM & Kotlin Multiplatform (soon) |
| ✅ Spec-conformant | Fully compliant with official TOON specification |
repositories {
mavenCentral()
}
dependencies {
implementation("br.com.vexpera:kotlin-toon:1.0.0")
}user:
name: "Alice"
age: 27
active: true
data class User(val name: String, val age: Int, val active: Boolean)
val text = """ user:\n name: "Alice"\n age: 27\n active: true """.trimIndent()
val root = toon(text)
val user = root["user"]!!.asObject<User>()project:
name: "Dream Engine"
authors[3]{id,name,role}:
1,Cláudio Marcelo Silva,lead
2,Jane Doe,artist
3,John Smith,engineer
data class Author(val id: Int, val name: String, val role: String)
val authors = toon(text)["project"]?.get("authors")?.asListOf<Author>()val data = mapOf(
"users" to listOf(
mapOf("id" to 1, "name" to "Alice"),
mapOf("id" to 2, "name" to "Bob")
)
)
println(Toon.encode(data))users[2]{id,name}:
1,Alice
2,Bob
val decoded = Toon.decode(text, DecodeOptions(strict = false))
val encoded = Toon.encode(data, EncodeOptions(indent = 4, lengthMarker = true))| Option | Description | |
|---|---|---|
strict |
Enables strict indentation & structure rules | |
lengthMarker |
Adds [n] to headers to enforce row count |
|
delimiter |
Use ,, ` |
, or \t` for table separation |
val name = toon(text)["user"]?.get("name")?.asString()
val users: List<User> = toon(text) { asListOf<User>() }Fully tested with:
- Conformance to official spec
- Round-trip integrity
- Tabular edge cases
- Lenient and strict modes
Run tests:
./gradlew testGradle:
implementation("br.com.vexpera:kotlin-toon:1.0.0")Maven:
<dependency>
<groupId>br.com.vexpera</groupId>
<artifactId>kotlin-toon</artifactId>
<version>1.0.0</version>
</dependency>- Path expansion and key folding (new in spec 1,5)
- KMP full support (JVM, Android, iOS, KotlinJS, Native)
- kotlinx.serialization support