Working with YAML in Kotlin: Library Overview and Usage Examples
YAML (YAML Ain't Markup Language) is a convenient data serialization format, often used for configuration files, describing API specifications (OpenAPI), and data exchange. In the Kotlin ecosystem, there are several mature libraries for working with YAML, each with its own features. In this article, we will look at three main approaches: using SnakeYAML, kaml, and kotlinx.serialization with the YAML format.
1. SnakeYAML — Classic Parser for JVM
SnakeYAML is the most popular Java library for working with YAML, which is fully compatible with Kotlin. It provides a low-level API for parsing and creating YAML documents.
Adding Dependency
Add the dependency to build.gradle.kts:
implementation("org.yaml:snakeyaml:2.2")Example: Reading YAML
Consider the file config.yaml:
server: host: localhost port: 8080database: url: jdbc:postgresql://localhost/mydb user: admin password: secretCode for parsing:
import org.yaml.snakeyaml.Yamlimport java.io.File
fun main() { val yaml = Yaml() val inputStream = File("config.yaml").inputStream() val data: Map<String, Any> = yaml.load(inputStream)
val server = data["server"] as Map<String, Any> println("Host: ${server["host"]}") println("Port: ${server["port"]}")
val db = data["database"] as Map<String, Any> println("DB URL: ${db["url"]}")}Example: Creating YAML
fun createYaml() { val data = mapOf( "appName" to "MyApp", "version" to "1.0.0", "features" to listOf("auth", "logging", "metrics") )
val yaml = Yaml() val writer = FileWriter("output.yaml") yaml.dump(data, writer) writer.close()}Pros of SnakeYAML:
- Maximum compatibility with Java projects
- Support for all YAML 1.1 features (anchors, tags, custom types)
- Flexible configuration via
DumperOptions
Cons:
- Works with raw types
Map<String, Any>— requires type casting - Does not support Kotlin data classes out of the box
2. kaml — Library for Kotlin with Data Class Support
kaml is a wrapper over SnakeYAML that adds support for deserialization into Kotlin data classes and serialization from them. The library uses Kotlin reflection for automatic mapping.
Adding Dependency
implementation("net.mamoe.yamlkt:yamlkt:0.13.0")Example: Deserialization into a Data Class
import net.mamoe.yamlkt.Yamlimport net.mamoe.yamlkt.YamlElement
data class ServerConfig( val host: String, val port: Int)
data class AppConfig( val server: ServerConfig, val debug: Boolean = false)
fun main() { val yaml = Yaml() val input = """ server: host: "0.0.0.0" port: 8080 debug: true """.trimIndent()
val config = yaml.decodeFromString(AppConfig.serializer(), input) println("Server: ${config.server.host}:${config.server.port}") println("Debug mode: ${config.debug}")}Example: Serialization
fun serializeConfig() { val config = AppConfig( server = ServerConfig("localhost", 9090), debug = false )
val yaml = Yaml() val output = yaml.encodeToString(AppConfig.serializer(), config) println(output)}Pros of kaml:
- Type safety — works with Kotlin data classes