Writing Kotlin in the Browser

Did you know that Kotlin can target JavaScript as well as the JVM? Don’t be too surprised if you didn’t know, as we’ve not been giving it too much coverage, despite already shipping a successful product that uses this capability. But here’s hoping to change things.

The Basics – A Simple Project

First step is to set up a new project. When using Kotlin in a project, we have the ability to target either the JVM or JavaScript. If we’re adding a new Kotlin file to an existing project, Kotlin will prompt us for this. If we’re starting a new project, we can choose the target during the setup wizard, assuming we’re using IntelliJ IDEA.

image

We also need to add the Kotlin standard library to the project. Clicking on the Create button we’ll be prompted with the location where we want these files copied. By default it copies is to a folder named script. And we’ll get to this later on as it’s important.

image

Project organization

The resulting structure of the project should be

image

The project has two files that are added:

  • The lib folder contains the header files, as a jar file, which are used during development.
  • The script folder contains a single kotlin.js which is the Kotlin runtime library. This is used in production.

All our Kotlin source code should be placed in the src folder. Once this is compiled, it will generate some JavaScript files that need to then be shipped along with the kotlin.js runtime file.

All other source code, be this external JavaScript libraries or files, CSS and HTML files can be placed anywhere, preferably in the same project to make development easier but not necessarily. For our example we’re going to place this in a folder called web and create a series of subfolders to structure our code.

image

Setting up a workflow

When we write Kotlin code,the compiler will generate some JavaScript which needs to be shipped as part of our application. By default, IntelliJ IDEA will output this file and its sourcemap to a folder named out/production/{project_name}

image

During development we need to have an up to date version of these files so ideally we’d like to have these located in our web/js/app folder. We can do this in many ways, either using IntelliJ IDEA artifacts or Maven/Gradle. In our case we’re just going to use an artifact. We can set one up to copy the corresponding files to the desired output location and additional also copy the kotlin.js file that was originally copied to the script folder to the same location*.

*This is a one-time operation so a better alternative is to define the output location of this file directly to our required output folder when setting up the project. We have done it this way to explain things step by step.

Interacting with DOM Elements

Now that we have the project layout ready, let’s start writing some code. The most basic thing we can do is manipulate some DOM elements. We can create a simple HTML page (named index.html) and place it under the web folder

<!DOCTYPE html>
<html>
<head>
<title>This page is manipulated with Kotlin</title>
</head>
<body>
<input type=”text” id=”email”>
</body>
</html>

The idea is to now update the value of the input field using Kotlin.  For that we can create a new file called main.kt and place it under our src folder.

Web-targeted Libraries

Kotlin provides a series of libraries targeted specifically at the web. In our case, since we want to manipulate the DOM, we can import the js.dom.html to access the document variable. The resulting code would be

package org.sample
import js.dom.html.document
fun main(args: Array<String>) {
document.getElementById(“email”).setAttribute
(“value”, “hello@kotlinlang.org”)
}

which is very straightforward. We’re using the document.getElementById to retrieve the DOM element and then setting its value using setAttribute. Exactly the same way we’d do it using JavaScript, except here we’re using Kotlin and have the benefit of static typing, among other things.

The standard library already provides support for DOM manipulation, HTML 5 features such as Canvas and Local Storage, as well as wrappers for common libraries such as jQuery. We will be adding more as we go along, and we’ll cover some of them in future posts.

Running the code

Now that we have the code compiled, we need to actually run it. For this we have to reference both the kotlin.js as well as the generated (basic.js) file from our index.html page.

<!DOCTYPE html>
<html>
<head>
<title>This page is manipulated with Kotlin</title>
</head>
<body>
<input type=”text” id=”email”>
<script src=”js/lib/kotlin.js”></script>
<script src=”js/app/basic.js”></script>
</body>
</html>

 

The code corresponding to the main function will automatically be called when the page is loaded.

Once we load our index.html page, we should see the result.

image

Calling Kotlin from JavaScript

What if we have some code in Kotlin we want to use from JavaScript? For instance, think of scenarios where you need to do some sort of business logic that needs to be repeated both on the client and the server. Well all we need to do is write it and then call it. Here is a simple function written in Kotlin

fun calculateTax(amount: Double): Double {
return amount + amount * 0.21
}

 

This is placed inside the same module as the application and we can call it referencing it by the Kotlin module name*

<input type=”button” value=”Calculate”
onclick=”alert(Kotlin.modules.basic.org.sample.calculateTax(200.0))”>

*This API is not final and will most likely change in the future, and probably will be much more compact.

Next Steps

That’s not all that is possible with Kotlin. One thing we haven’t mentioned is the ability to call JavaScript code from within Kotlin and that is something we’ll be covering in a another post, as this one has already become too long!

If you want to play with Kotlin to JavaScript without having to install anything, you can also try it directly in the browser. And as always, give us your feedback!

This entry was posted in General and tagged . Bookmark the permalink.

19 Responses to Writing Kotlin in the Browser

  1. Aleksey Zhidkov says:

    Wow, just decided to give Kotlin another chance and immediately foundthis post:) So you’re got it:) Thanks for your work

  2. Paul Eden says:

    I am loving this and getting excited about the possibilities!

    For simplicity, I made web/js/app as my project compiler output location in the Project Settings, but that caused that directory to be excluded and hence I don’t have any autocomplete for it in the index.html file and an inspection says it can’t find the file even though it is there.

    Could you elaborate more on the following?
    - Is the best practice to create an artifact to copy the files then and if so how do you do that?

    During development we need to have an up to date version of these files so ideally we’d like to have these located in our web/js/app folder. We can do this in many ways, either using IntelliJ IDEA artifacts or Maven/Gradle. In our case we’re just going to use an artifact. We can set one up to copy the corresponding files to the desired output location and additional also copy the kotlin.js file that was originally copied to the script folder to the same location*.

    *This is a one-time operation so a better alternative is to define the output location of this file directly to our required output folder when setting up the project. We have done it this way to explain things step by step.

    • Hadi Hariri says:

      1. Go to Module Settings for the Project.
      2. Click on Artifacts and click on the + sign in the middle column to create a new one
      3. Select Other
      4. In the Output Layout, on the left panel, click + sign and find the location of your output folder
      5. At the top part, make the Output Directory point to web/js/app (fix the previous step you made of making that the output folder of project)
      6. Click on the Build on Make

      If you don’t want to copy kotlin.js each time, just copy it manually once.

  3. Pingback: Links & reads for 2013 Week 42 | Martin's Weekly Curations

  4. Maksym Ternovenko says:

    Hi,

    I’m wondering is it possible to use Kotlin with Node js?
    For example use Express as web framework & Kotling for business logic

    • Hadi Hariri says:

      In principle you should be able to. It’s just generating plain JavaScript and we will have compatibility with CommonJS module systems. There’s also the option of doing the Express stuff in Kotlin. I’ve actually written an Express-style framework: http://github.com/hhariri/wasabi. Still work needed but it’s following the same concepts as Express.

  5. Guest says:

    I have to say that the mentioned DOM API example is a bit underwhelming:
    document.getElementById("email").setAttribute("value", "hello@kotlinlang.org")
    I.e. the setAttribute method that takes two strings has exactly the same amount of type safety as one would have with JavaScript – that is to say ‘none’. In contrast, it would be truly exciting to be able to write something like this:
    document.getElementById("email").value = "hello@kotlinlang.org"

  6. Alex says:

    That’s awesome — any plans to target asm.js?

    • Zalim Bashorov says:

      Current version of asm.js is not intended to use as a target for managed languages (see asm.js faq) and it supports only in one browser — FireFox.

      Right now we don’t have any plans about it, but we continue to follow this project.

  7. Pingback: Java & Things

  8. Victor says:

    @Hadi Very interesting article, thanks. Great potential.
    Sadly, at about middle of article, the example code “index.html” for “Interacting with DOM Elements” is missing the closing pre-tag, which makes the 2nd half of the article almost unreadable. Please could you fix that?

  9. Norbert Sándor says:

    When can we expect an Eclipse plugin? Thanks!

    • Hadi Hariri says:

      There are a couple of community projects for Kotlin / Eclipse and we hope that at some point we can contribute.

  10. B7W says:

    Is there way to configure gradle project to compile kolin to js?

  11. Cliff says:

    Is there any way to associate original source to running JavaScript, as in via a source map, for debugging?

  12. Cliff says:

    I was following your instructions and got this.

    GET http://localhost:63342/untitled/web/%E2%80%9Djs/lib/kotlin.js%E2%80%9D 404 (Not Found)

    I am pretty sure that it was due to me setting up the Artifact in a faulty way. Could you perhaps provide more explicit instructions? If you follow your instructions line by line, the IDE seems to provide more dialogs than there are instructions for, if that makes sense.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">