Kotlin/JS — компајлер Kotlin кода у JavaScript, који омогућава креирање фронтенд апликација и веб-интерфејса на језику Kotlin. За разлику од TypeScript-а, Kotlin/JS пружа строгу статичку типизацију, подршку за корутине и беспрекорну интеграцију са Kotlin Multiplatform. Почев од Kotlin 1.8, компајлер користи IR-базирани бекенд за генерисање оптимизованог JavaScript кода. Према подацима JetBrains, 2025, Kotlin/JS подржава интеграцију са NPM екосистемом и TypeScript-ом кроз аутоматско генерисање .d.ts датотека.
Главне тачке
Kotlin/JS — један је од три бекенда компајлера Kotlin (поред JVM и Native), намењен за превођење Kotlin кода у JavaScript. Развијен од стране JetBrains-а, Kotlin/JS омогућава писање веб апликација на језику са строгом статичком типизацијом, задржавајући приступ огромном екосистему JavaScript библиотека кроз механизам спољашњих декларација. Од првог стабилног издања у Kotlin 1.3, компајлер је прешао пут од експерименталног бекенда до production-ready алата који се користи у индустријским пројектима.
Основна намена Kotlin/JS — фронтенд развој коришћењем Kotlin уместо JavaScript или TypeScript. Програмери добијају све могућности језика Kotlin: null safety, екстензионе функције, data класе, корутине и sealed класе. Генерисани JavaScript код може да се извршава у било ком модерном прегледачу или Node.js окружењу. Kotlin/JS је посебно тражен у Kotlin Multiplatform пројектима, где је заједнички модул (commonMain) доступан и за мобилне и за веб апликације.
Екосистем Kotlin/JS укључује фрејмворке за креирање корисничких интерфејса. Compose Multiplatform за веб користи Kotlin/JS као циљни бекенд, што омогућава креирање декларативних UI компоненти које раде у прегледачу. Алтернативна решења укључују омотаче за React — Kotlin Wrappers, који пружају type-safe API за React, React Router и Redux.
Компилација Kotlin/JS пролази кроз неколико фаза трансформације. Изворни Kotlin код се прво компилира у посредну репрезентацију (IR), затим оптимизује и генерише се JavaScript код. Почев од Kotlin 1.8, стари бекенд (JsBackend заснован на AST) је потпуно замењен IR-бекендом, који обезбеђује бољу оптимизацију, мању величину излазног кода и компатибилност са TypeScript-ом.
Раније је Kotlin/JS користио JsBackend, који је радио директно са AST стаблом (Abstract Syntax Tree). Овај приступ је имао ограничења: сложеност подршке за платформске оптимизације, недостатак јединственог IR за све бекенде и немогућност генерисања TypeScript декларација. Прелазак на IR-бекенд је решио ове проблеме, унифицирао компилацију сва три Kotlin бекенда и отворио пут за унакрсне бекенд оптимизације.
Kotlin/JS подржава два режима компилације који одређују формат и оптимизацију излазног кода. Production режим користи Webpack за компилацију, минификацију и tree-shaking. Development режим подржава Hot Module Replacement за брзу итерацију током развоја. Избор режима се подешава у build.gradle.kts кроз конфигурацију js.target.
kotlin {
js {
browser {
webpackTask {
outputFileName = "app.js"
}
}
binaries.executable()
}
}
Интеграција Kotlin/JS са NPM екосистемом реализована је кроз посебан DSL у build.gradle.kts. Програмер декларише npm зависности у конфигурацији kotlin, наводећи име пакета и верзију. Kotlin/JS аутоматски преузима пакете преко менаџера пакета npm или yarn. За обезбеђивање type-safe приступа JavaScript библиотекама користе се external декларације, које описују типове и функције библиотеке за Kotlin компајлер.
External декларације — Kotlin декларације означене кључном речи external. Оне обавештавају компајлер да се имплементација функције или класе налази у JavaScript коду, а не у Kotlin-у. JetBrains обезбеђује готове скупове омотача за популарне библиотеке у оквиру Kotlin Wrappers, укључујући React, React Router, Redux, Emotion и MUI. За библиотеке које немају готове омотаче, програмер може написати external декларације ручно или користити генератор TypeScript веза Dukat.
kotlin {
js {
browser { }
npm {
dependency("react", "18.3.1")
dependency("react-dom", "18.3.1")
devDependency("webpack", "5.92.0")
}
}
}
// Спољашња декларација за JavaScript библиотеку
@JsModule("date-fns")
external fun formatDistance(
date: Date, baseDate: Date
): String
TypeScript — саставни део модерног веба, а Kotlin/JS обезбеђује компатибилност са њим кроз генерисање .d.ts датотека. При подешавању js.generateTsDeclarations = true, компајлер креира TypeScript декларације за све јавне Kotlin функције и класе. Ово омогућава TypeScript пројектима да импортују Kotlin модуле са пуном подршком типова. Генерисање TypeScript декларација ради само са IR-бекендом и један је од кључних разлога миграције са старог бекенда.
IR-бекенд (Intermediate Representation) — јединствени бекенд за све три платформе Kotlin: JVM, JS и Native. Користи заједничку посредну репрезентацију која пролази кроз неколико фаза оптимизације пре генерисања циљног кода. За Kotlin/JS, IR-бекенд је постао обавезан од Kotlin 1.8.0, заменивши стари AST-базирани бекенд који је означен као deprecated.
Предности IR-бекенда за Kotlin/JS укључују побољшану оптимизацију кода на IR нивоу, смањење величине бандла кроз елиминацију мртвог кода и inline оптимизације, као и подршку за TypeScript декларације. IR-бекенд такође обезбеђује коректну обраду inline функција, reified generic-а и suspend функција при превођењу у JavaScript, што је било проблематично у старом бекенду.
| Карактеристика | Стари бекенд (AST) | IR-бекенд |
|---|---|---|
| TypeScript декларације | Нису подржаване | Генеришу се аутоматски |
| Елиминација мртвог кода | Ограничена | Потпуна, на IR нивоу |
| Inline функције | Проблеми са коректношћу | Коректна обрада |
| Reified generic-и | Нису подржавани | Подржавани |
| Величина бандла | Основна | 20–30% мања |
Пуноправни Kotlin/JS пројекат почиње конфигурацијом build.gradle.kts. Плагин kotlin multiplatform омогућава подешавање Kotlin/JS као једне од циљних платформи. Размотримо пример подешавања за веб апликацију са React-ом.
plugins {
kotlin("multiplatform") version "2.0.21"
id("org.jetbrains.kotlin-wrappers") version "1.0.0-pre.775"
}
kotlin {
js {
browser { }
binaries.executable()
generateTsDeclarations = true
}
}
dependencies {
implementation(enwraps(react, reactDom))
}
Након подешавања, могуће је писати React компоненте у Kotlin-у. Kotlin Wrappers пружају type-safe API за React, укључујући функционалне компоненте, hook-ове и JSX-сличну синтаксу кроз DSL градитеље. Пример Counter компоненте демонстрира рад са useState и управљачима догађаја.
@OptIn(ExperimentalWrapperApi::class)
val Counter = FC<Props> {
var count = useState(0)
div {
+"Counter value: ${count.component1()}"
button {
onClick = { count.component2()(count.component1() + 1) }
+"Increment"
}
}
}
fun main() {
createRoot(document.getElementById("root")!!).render(
createElement(Counter)
)
}
Изградња Kotlin/JS пројекта се извршава кроз Gradle задатке. jsDevelopmentRun покреће dev-server Webpack са HMR за развој. jsProductionExecutableCompileSync генерише production бандл са минификацијом и tree-shaking-ом. Коначна HTML датотека која повезује компилирани JavaScript генерише се од стране webpack плагина и налази се у build/dist.
// Покрени dev сервер са HMR
./gradlew jsDevelopmentRun
// Production изградња са минификацијом
./gradlew jsProductionExecutableCompileSync
// Излаз у build/dist/productionExecutable/
TypeScript — главни конкурент Kotlin/JS у области типизираног JavaScript-а. Оба језика се компилирају у JavaScript и додају статичку типизацију на динамички JS. Међутим, Kotlin/JS нуди низ предности: null safety подразумевано, sealed класе, корутине и беспрекорну интеграцију са Kotlin Multiplatform. TypeScript, са своје стране, има већу заједницу, више готових библиотека са типовима и зрелији екосистем.
Продуктивност развоја на Kotlin/JS може бити већа за тимове који већ користе Kotlin у другим деловима пројекта, јер не захтева пребацивање између језика. TypeScript остаје популарнији избор за чисте веб пројекте где се не користи Kotlin Multiplatform. Међутим, са порастом популарности Compose Multiplatform за веб, Kotlin/JS добија на значају као алтернатива React-у и Angular-у.
| Карактеристика | Kotlin/JS | TypeScript |
|---|---|---|
| Null safety | Подразумевано | strictNullChecks опционално |
| Sealed класе | Подржаване | Кроз union типове |
| Корутине | Изворно | Кроз async/await |
| KMM интеграција | Потпуна | Не постоји |
| Величина заједнице | Мала | Огромна |
| Готови типови за библиотеке | Ограничени (DefinitelyTyped преко Dukat) | DefinitelyTyped (хиљаде библиотека) |
Избор између Kotlin/JS и TypeScript зависи од контекста пројекта. Ако тим већ користи Kotlin Multiplatform или планира да почне, Kotlin/JS је логичан избор за фронтенд део. За изоловани веб пројекат, TypeScript остаје прагматичније решење због доступности готових типова за JavaScript библиотеке и већег броја програмера на тржишту.
Често постављана питања
Да, JetBrains обезбеђује Kotlin Wrappers — type-safe Kotlin омотаче за React, React Router и Redux. Они омогућавају писање React компоненти у Kotlin-у са пуном подршком за hook-ове и JSX-сличан DSL.
При укључивању generateTsDeclarations = true, Kotlin/JS генерише .d.ts датотеке за све јавне API-је. TypeScript пројекти могу да импортују Kotlin модуле са пуном типизацијом као обичне npm пакете.
Величина бандла зависи од коришћених библиотека. Минимална Hello World апликација заузима око 300 KB укључујући Kotlin stdlib. Са React-ом и Kotlin Wrappers-има величина расте на 400–600 KB.
Да, Kotlin/JS се може користити за развој serverless функција и конзолних алата под Node.js. За то је у конфигурацији потребно навести js.nodejs уместо js.browser.
Kotlin/Wasm — експериментални бекенд за WebAssembly, док Kotlin/JS генерише JavaScript код. Wasm пружа веће перформансе, али има ограничен приступ прегледачком DOM-у.
Закључак
Развићемо мобилну апликацију под кључ
IT Sectr креира iOS и Android апликације за стартапе и предузећа од 2017. године. Саветоваћемо вас и предложити најбоље решење.
Прочитајте такође