Simple HTML DSL for Kotlin
By Mikael Ståldal
As I wrote a while ago, I have been trying different approaches for server-side HTML generation in Kotlin, with focus on good support for generating partials without a single root element (which is important for htmx).
Given Kotlin’s good support for internal DSLs, I decided to explore that route, and try kotlinx.html and HtmlFlow. They both make great promises of encoding the entire HTML standard and enforce valid HTML at compile time. This sounds very nice in theory, but in practice they are quite a disappointment.
As you can see in my sample project with kotlinx.html, integrating it with http4k is a slightly cumbersome for complete pages, and really annoying for partials. It also contributes significantly to compile time, and is not particularly fast at runtime according to some benchmarks.
I also wanted to give HtmlFlow a try, but it was unreasonably difficult to get it to work in a convenient way when using data binding, layout and fragments at the same time, so I gave up. Here is my incomplete and unsuccessful attempt.
My conclusion is that those two type-safe internal DSLs for HTML are just too heavy and complicated. They have some advantages, but it’s not worth the added complexity, cognitive load and increased compile time.
So I decided to try if I could make something simpler myself, inspired by kotlinx.html and Kotlin XML builder. However, both of those builds an internal tree representation before generating HTML, usually to just throw it away when after generating HTML once. I realized that was wasteful, so I decided to skip that and generate HTML directly, only create one object to keep some state during generation.
For me, it was easier to write my own library from scratch, than trying to figure out how to use kotlinx.html or HtmlFlow in a reasonable way.
The result: Kotlin HTML builder. I also made a simple example on how to use it, and a benchmark showing it is about twice as fast as kotlinx.html (though still slower than HtmlFlow).