0Pricing
Kotlin Academy · Lesson

Building a Type-Safe HTML/Config DSL

Implement a simple configuration DSL using builder patterns and extension lambdas.

Goal: A Practical DSL

We will build a minimal but realistic HTML builder DSL in Kotlin. The same patterns apply to any config, test fixture, or report builder. The result is a typesafe, IDE-friendly API that replaces string concatenation.

Define the Tag Base Class

All HTML elements share a common shape: a name, attributes, and children. Start with a base class:

open class Tag(val name: String) {
    val attrs = mutableMapOf<String, String>()
    val children = mutableListOf<Tag>()
    fun render(indent: Int = 0): String {
        val pad = " ".repeat(indent)
        val attrStr = if (attrs.isEmpty()) "" else " " + attrs.entries.joinToString(" ") { "${it.key}=\"${it.value}\"" }
        val body = children.joinToString("\n") { it.render(indent + 2) }
        return "$pad<$name$attrStr>\n$body\n$pad</$name>"
    }
}

All lessons in this course

  1. Lambda with Receiver: The DSL Foundation
  2. @DslMarker: Preventing Receiver Leakage
  3. Building a Type-Safe HTML/Config DSL
  4. Testing and Evolving DSLs Without Breaking Users
← Back to Kotlin Academy