Files
kotlin-cloudflare-worker/README.md
T
2026-01-04 00:33:42 +08:00

4.4 KiB

Kotlin cloudflare worker

A library to running kotlin/js on cloudflare worker.

Get started

Setup

kotlinx.coroutines is required

plugins {
    kotlin("multiplatform") version "2.2.21"
}

repositories {
    mavenCentral()
    maven("https://repo.maven.rtast.cn/releases")
}
// to get latest version of this lib, go to 
// https://next.pkg.rtast.cn/#/releases/cn/rtast/kotlin-cfworker/core/
implementation("cn.rtast.kotlin-cfworker:core:1.0.2")

Run app

kotlin {
    js(IR) {
        nodejs {
            outputModuleName = "kotlin-cloudflare-worker"
            binaries.executable()
        }
    }
}

Minimal hello world app

/**
 * DO NOT EDIT THIS FUNCTION
 */
fun main() {
    @Suppress("unused_expression")
    val eventListener = EventListener { event ->
        val dyn = event.asDynamic()
        event.asDynamic().respondWith(handleRequest(dyn.request as Request))
        Unit
    }
    js("addEventListener('fetch', eventListener)")
}

@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
    val server = WorkerApplication().apply {
        route("/") {
            respondText("Hello kotlin cloudflare worker")
        }
    }
    return@promise server.handle(request)
}

Before run worker locally, you need to install wrangler and login

First, create wrangler.toml in your root project and configure it

name = "kotlin-cloudflare-worker"  # any name you want
account_id = "<your account id>"
workers_dev = false
preview_urls = false
compatibility_date = "2022-08-11"
main = "kotlin-cloudflare-worker.js"  # Set this value same as `outputModuleName`

Then run gradle task gradlew compileProductionExecutableKotlinJs, copy wrangler.toml into build/compileSync/js/main/productionExecutable/kotlin, and run wrangler dev command in build/compileSync/js/main/productionExecutable/kotlin,

Deploy

Run gradle task, copy wrangler.toml, but use wrangler deploy to deploy to cloudflare worker

Note

JavaScript uses a single-threaded execution model. All asynchronous work is ultimately driven by the event loop ( including Kotlin coroutines on JS).

Therefore, DO NOT create a CoroutineScope(Dispatchers.Default) or launch CPU-bound coroutines, as there is no real background thread on JS targets.

All coroutines run on same event loop thread, and all coroutines not in same event loop will be dropped.

Example:

// DO NOT DO THIS
val scope = CoroutineScope(Dispatcher.DEFAULT)

fun blockingFunction() {
    scope.launch {
        // this block will never execute
    }
}

// Instead of do this

fun main() {
    @Suppress("unused_expression")
    val eventListener = EventListener { event ->
        val dyn = event.asDynamic()
        event.asDynamic().respondWith(handleRequest(dyn.request as Request))
        Unit
    }
    js("addEventListener('fetch', eventListener)")
}

@JsExport
fun handleRequest(request: Request): Promise<Response> = GlobalScope.promise {
    return Promise.resolve(Response("Hello"))
}

Http client

Cloudflare worker is not a standard nodejs environment, do http requests must use fetch api(not window.fetch, this is browser api), use cn.rtast.cfworker.client.fetch instead,

ByteArray and ByteBuffer cast

Kotlin cloudflare worker provided api to mutual conversion,

import cn.rtast.cfworker.util.toByteArray
import cn.rtast.cfworker.util.toArrayBuffer

val bb: ByteBuffer = ...
// convert ByteBuffer to ByteArray
val ba: ByteArray = bb.toByteArray()

// convert ByteArray to ByteBuffer
val bb2: ByteBuffer = ba.toArrayBuffer()

CPU Time limit

Cloudflare worker free tier have a limit of worker cpu limit (10ms, exclude IO waiting time), kotlin cloudflare worker depends on kotlin-stdlib and kotlinx.coroutines, which are quite heavy*, When performing CPU-bound task, please carefully consider whether to use JavaScript instead of Kotlin.

But it works for my maven repository, I registered over 15 api endpoints. The avg cpu time for each endpoint does not exceed 10ms, but it may increase significantly during cold start (Over 50-200ms, but still responsible)

avg-cpu-time

This image shows last 24 hours avg cpu time, see P50

Real instance

https://repo.maven.rtast.cn

Yes, it the maven repository but built with kotlin/js with this lib