Creating an amazingly simple HTML builder in Kotlin.

Joost Klitsie
4 min readJul 22, 2023

--

Let’s explore how we can use the Kotlin programming language to build a simple, yet effective, DSL to generate HTML code. In a previous article I showed how to use Kotlin language features like extension functions and lambdas with receivers to create awesome builders in Kotlin. If you are unknown to Kotlin or the aforementioned language features, I highly recommend to read that article first before continuing on this one. With that out of the way, let’s get started with writing our own HTML builder! First we create the most basic of things, an interface for any element in our HTML tree, albeit an html tag or just simple text:

Here we sneak in yet another nifty Kotlin feature: functional interfaces. Functional interfaces are interfaces with a single abstract function, and it is the same as SAM interfaces in Java and can be instantiated in the same way. However, adding the “fun“ keyword will add compile time checks to make sure we are not able to add more methods providing more safety. Our render function is expected to output an HTML string with the appropriate indentation for better readability.

After we have defined our HtmlElement, we should create a tag class with a builder. We expect our tag class to hold 3 different fields: Name of the tag, attributes and child elements.

This is a tag with name TagName, 1 attribute called attribute and it has 1 text child. With this information we can construct our HtmlTag class which includes the builder.

You can see that the constructor of HtmlTag is private, and the properties are immutable values. The HtmlTag.Builder class mirrors the properties, but they are mutable instead. You can see that aside from the mandatory name, the fields defined in the builder constructer have default values. So, by default you must pass the name of the tag you wish to build, and by default it will have no attributes or children. The render function in HtmlTag first constructs a string from the attributes and then either generates a childless tag, like <br /> or a full tag including children. The children will also be joined to string, separated with a new line, and get an extra indent as we go deeper into the HTML tree.

The HtmlTag.Builder is very clean and only contains 1 method which we use to build the actual HtmlTag. We provided access to all its properties, and now it is time to write the actual HtmlBuilder using this as the foundation.

Let’s start with the basic: Creating the root HTML tag. We create a simple method to create our root tag:

Now generating our HTML, even though it is empty, will look like this:

After that we can add helper, or extension, methods to add attributes and children to our html builder. We have a mutable field with an immutable map for the attributes and another mutable field with an immutable list for children. We can add these helper methods to add elements to these collections:

Great, good start! One more method to go and we can make our html output already more interesting. We will add a simple text as a child element. To do this, we create an extension function that adds a simple text HtmlElement. The following code calls the previously declared addChild function, and it also uses the SAM constructor to instantiate this:

Did I mention Kotlin is concise? (Yes, I did!) You can see that on any HtmlTag.Builder object, we can call text(..) which adds a text child. It also considers proper indentation, so let’s try it out by adding some text to our initial html:

That is great! Now all we have to do, is create a good way to add some more children tags. To achieve this, we can create yet another extension function to create simple tags. The steps will be: Create a new HtmlTag.Builder object, configure it and add it as a child to the current tag builder. These are almost the same steps as what happens in the html(..) function. Let’s make it more concise though:

Here you can see we add a child to the HtlmTag.Builder receiver object, which is a HtmlTag with a certain name and a configuration. To use this, we can write for example this:

Now we are almost there! Let’s create some handy helper methods and finish off with our simple HTML builder:

After that we also write some code to actually generate our html:

You can see that this code has a similar structure to the HTML that we expect it to produce. We are also able to use computations and dynamically generate whatever HTML we want. If we run this code, we will see the following output:

Fantastic! As you can see, the structure of the output matches the Kotlin code we wrote to generate the HTML. Also, the DSL is easy to read, understand and to extend. We have only written a few functions, but nothing stops you from writing your own extension functions and create a more complex builder pattern. But, before you start copy/pasting this and write your own HTML builder in Kotlin, there is already a great library provided by JetBrains (the creators of Kotlin) out there to help you generate HTML for Javascript or JVM: kotlinx.html.

Using the Kotlin builder pattern with extension functions and lambdas with receivers is a great way to write concise and understandable code. Because of the syntax, you can easily create complex trees, unlike the good old fashioned Java builder pattern. This is not only helpful for HTML, but also for any other UI library (see Jetpack or JetBrains Compose) and you can even write your backend and routing using such builder functions with Ktor. Here in this article, I showed you that Kotlin provides great and intuitive ways to write code. Until next time!

--

--

Joost Klitsie

I am developing Android Applications for over 10 years, with a passion for Kotlin, and won Best of Swiss Apps in 2023 with my team.