Fork me on GitHub
  1. What is Kweb?
  2. Features
  3. How does it work?
  4. What does it look like?

What is Kweb?

Kweb is a library for building rich web applications in the Kotlin programming language. You can think of it as a powerful Kotlin DSL that allows you to remote-control web browsers from a web server.

Even though your code runs on the server, Kweb allows you to interact with the browser DOM directly, for example here we create a <p> element and set its text:

doc.body.p().setText("this is an example HTML paragraph")

You can also interact with JavaScript directly, although you should rarely need to do this:

doc.body.execute("console.log((new Date()).getDay());")

You can even query JavaScript and do something with the result:

val day = doc.body.evaluate("$('#day').text()")
database.update(BOOK).set(BOOK.DAY, day).execute()

But Kweb’s real power is what’s built on top of this low-level framework. Through its plugin mechanism Kotlin lets you use powerful JavaScript libraries like Material Design Lite through a Kotlin DSL that mirrors the library’s API, but with the benefits of Kotlin’s DSL-friendly syntax and its type safety:

header().apply {
  row().apply {
     navigation().apply {
       navLink().setText("Delete") {

Aside from Material, Kotlin has plugins for JavaScript libraries like JQuery, select2, and others. It’s also surprisingly easy to build your own plugins for other JavaScript libraries, or extend those Kweb already supports.


  • Build websites in Kotlin
  • Interact with the user just like powerful but complex JavaScript frameworks like React or Angular
  • Makes the barrier between web-browser and web-server largely invisible
  • Seamlessly integrates with powerful JavaScript libraries like JQuery, MDL, and Bootstrap
  • Update your web browser instantly in response to code changes
  • Easy to add to an existing project, Kweb is just a library, it doesn’t seek to tell you how your project should be organized

How does it work?

Kweb keeps all of the logic server-side, and uses efficient websockets to communicate with web browsers. We also take advantage of Kotlin’s powerful new coroutines mechanism to efficiently handle asynchronicity, largly invisibly to the programmer.

What does it look like?

Here we create a simple “todo” list app:

fun main(args: Array<String>) {
    Kweb(8091, debug = true) {
        doc.body.apply {
            h1().addText("Simple Kweb demo - a to-do list")
            p().addText("Edit the text box below and click the button to add the item.  Click an item to remove it.")

            val ul = ul().apply {
                for (text in listOf("one", "two", "three")) {

            val inputElement = input(type = InputType.text, size = 20)

            val button = button()
            button.addText("Add Item")
                future {
                    val newItemText = inputElement.getValue().await()

fun ULElement.newListItem(text: String) {
    li().apply {
        addText(text) { event ->
            delete() }

Next: Setting Up »»