Kotlin-js, dce & closure compiler

I’ve been playing with kotlin-js (see the ui directory in this project). In the documentation it is suggested that using the google closure compiler & dce plugins might be a good thing for production code. I’m struggling with both and the documentation is less than helpful on this front currently and there seems to be a general lack of examples using both. Google is of course less than helpful when most documentation for this is years old and not relevant for current versions of kotlin-js.

Basically the only thing that actually works in a browser is the enormous js file produced by the kotlin-js file. I’d like a properly minified version of that with source maps please.

Here’s my gradle file. I’m attempting to import left-pad as a proof of concept. I’ve enabled dukat via kotlin.js.experimental.generateKotlinExternals=true in gradle.properties.

plugins {
    id("org.jetbrains.kotlin.js") version "1.3.61"

apply {
    // this plugin minifies the kotlin js output. Several bugs currently with this (e.g. multiple npms having an index.js)

group = "com.jillesvangurp"
version = "1.0-SNAPSHOT"

repositories {

val closureCompiler by configurations.creating

dependencies {
    // needed for the google closure compiler, which is recommended to minify the output of dce

kotlin {
    sourceSets["main"].dependencies {
        // set kotlin.js.experimental.generateKotlinExternals=true in gradle.properties for dukat to do its thing

        implementation(npm("left-pad", "1.3.0"))
    target {

        browser {
            webpackTask {


tasks {
    register<Copy>("copy-index-html") {

    register<Copy>("copy-dce-html") {
    // does not work because of module errors
    register<JavaExec>("googleClosureCompileDceJs") {
        classpath = closureCompiler
        main = "com.google.javascript.jscomp.CommandLineRunner"
        args = listOf(
//            "--process_common_js_modules", // errors with a  ERROR - [JSC_INVALID_MODULE_PATH] Invalid module path "kotlin" for resolution mode "BROWSER"
            // nope, this doesn't work either
            // this is left-pad, which the dce plugin fails to name properly. Also, you can only have 1 file called index.js

    // processes the output in distributions (12M) and produces a similarly sized file that does not work (unlike the original)
    register<JavaExec>("googleClosureCompileDistributionJs") {
        classpath = closureCompiler
        main = "com.google.javascript.jscomp.CommandLineRunner"
        args = listOf(

There are multiple problems that I’m chasing with this.

  • gradle run --continuous works fine but the output in distributions is huge.
  • the dce output is a lot smaller but I’ve yet to find a way to make it work. I attempted to load this via the dce.html that explicitly names each module in the (supposed) order they need to be loaded.
  • I’ve defined two variants of using the closure compiler.
    • The first one works on the dce output and this doesn’t load (some error about modules when you load the html).
    • The second one works on the output in distributions (non dce) this produces a similarly huge file that unlike the original does not load

Both of the tasks copy files to a packaged directory.

I’d appreciate feedback on how to improve this and get it in a working state.

I’d also humbly suggest updating the documentation with working configuration for dce and the closure compiler. Even what I did seems useful (despite not producing useful output) since it at least has a working config for pulling in the closure compiler, which is something that required a bit of research on my side as absolutely nothing with the kotlin dsl is straightforward.

Currently the tests don’t work. I suspect the leftpad dependency is guilty.

1 Like