Kotlin/JS — کامپایلری است که کد Kotlin را به JavaScript تبدیل میکند و امکان ایجاد برنامههای frontend و رابطهای وب به زبان Kotlin را فراهم میکند. برخلاف TypeScript، Kotlin/JS تایپاستاتیک سختگیرانه، پشتیبانی از کوروتینها و یکپارچگی seamless با Kotlin Multiplatform را فراهم میکند. از Kotlin 1.8، کامپایلر از IR-based backend برای تولید کد JavaScript بهینهشده استفاده میکند. به گفته JetBrains، 2025، Kotlin/JS از یکپارچگی با اکوسیستم NPM و TypeScript از طریق تولید خودکار فایلهای .d.ts پشتیبانی میکند.
نکات اصلی
Kotlin/JS — یکی از سه backend کامپایلر Kotlin (در کنار JVM و Native) است که برای ترجمه کد Kotlin به JavaScript طراحی شده است. Kotlin/JS که توسط JetBrains توسعه یافته، امکان نوشتن برنامههای وب به زبانی با تایپاستاتیک سختگیرانه را فراهم میکند و دسترسی به اکوسیستم عظیم کتابخانههای JavaScript را از طریق مکانیزم اعلانهای خارجی حفظ میکند. از اولین انتشار پایدار در Kotlin 1.3، کامپایلر از یک backend آزمایشی به ابزاری آماده تولید تبدیل شده است که در پروژههای صنعتی استفاده میشود.
هدف اصلی Kotlin/JS — توسعه frontend با استفاده از Kotlin به جای JavaScript یا TypeScript است. توسعهدهندگان تمام قابلیتهای زبان Kotlin را دریافت میکنند: null safety، توابع توسعهدهنده، کلاسهای data، کوروتینها و کلاسهای sealed. کد JavaScript تولیدشده میتواند در هر مرورگر مدرن یا محیط Node.js اجرا شود. Kotlin/JS به ویژه در پروژههای Kotlin Multiplatform مورد تقاضا است، جایی که ماژول مشترک (commonMain) هم برای برنامههای موبایل و هم برای وب در دسترس است.
اکوسیستم Kotlin/JS شامل فریمورکهایی برای ایجاد رابطهای کاربری است. Compose Multiplatform برای وب از Kotlin/JS به عنوان backend هدف استفاده میکند که امکان ایجاد کامپوننتهای UI اعلامی را فراهم میکند که در مرورگر کار میکنند. راهحلهای جایگزین شامل wrapperهایی برای React — Kotlin Wrappers هستند که API type-safe برای React، React Router و Redux ارائه میدهند.
کامپایل Kotlin/JS از چند مرحله تبدیل عبور میکند. کد منبع Kotlin ابتدا به نمایش میانی (IR) کامپایل میشود، سپس بهینهسازی شده و کد JavaScript تولید میشود. از Kotlin 1.8، backend قدیمی (JsBackend مبتنی بر AST) کاملاً با IR-backend جایگزین شده است که بهینهسازی بهتر، اندازه کد خروجی کوچکتر و سازگاری با TypeScript را فراهم میکند.
قبلاً Kotlin/JS از JsBackend استفاده میکرد که مستقیماً با درخت AST (Abstract Syntax Tree) کار میکرد. این رویکرد محدودیتهایی داشت: پیچیدگی پشتیبانی از بهینهسازیهای پلتفرمی، عدم وجود IR یکپارچه برای همه backendها و ناتوانی در تولید اعلانهای TypeScript. انتقال به IR-backend این مشکلات را حل کرد، کامپایل هر سه backend Kotlin را یکپارچه ساخت و راه را برای بهینهسازیهای متقابل backend باز کرد.
Kotlin/JS از دو حالت کامپایل پشتیبانی میکند که فرمت و بهینهسازی کد خروجی را تعیین میکنند. حالت production از Webpack برای کامپایل، minification و 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 مجموعههای آماده wrapper را برای کتابخانههای محبوب در قالب Kotlin Wrappers ارائه میدهد، از جمله React، React Router، Redux، Emotion و MUI. برای کتابخانههایی که wrapper آماده ندارند، توسعهدهنده میتواند اعلانهای 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-backend کار میکند و یکی از دلایل اصلی مهاجرت از backend قدیمی است.
IR-backend (Intermediate Representation) — backend یکپارچه برای هر سه پلتفرم Kotlin: JVM، JS و Native است. از یک نمایش میانی مشترک استفاده میکند که قبل از تولید کد هدف از چند مرحله بهینهسازی عبور میکند. برای Kotlin/JS، IR-backend از Kotlin 1.8.0 اجباری شد و backend قدیمی مبتنی بر AST که به عنوان deprecated شده بود را جایگزین کرد.
مزایای IR-backend برای Kotlin/JS شامل بهینهسازی بهبودیافته کد در سطح IR، کاهش اندازه باندل از طریق حذف کد مرده و بهینهسازیهای inline، و همچنین پشتیبانی از اعلانهای TypeScript است. IR-backend همچنین پردازش صحیح توابع inline، genericهای reified و توابع suspend را در ترجمه به JavaScript تضمین میکند که در backend قدیمی مشکلساز بود.
| ویژگی | Backend قدیمی (AST) | IR-backend |
|---|---|---|
| اعلانهای TypeScript | پشتیبانی نمیشد | تولید خودکار |
| حذف کد مرده | محدود | کامل، در سطح IR |
| توابع inline | مشکلات صحت | پردازش صحیح |
| Genericهای reified | پشتیبانی نمیشد | پشتیبانی میشود |
| اندازه باندل | پایه | 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 API type-safe برای 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 سرور توسعه Webpack را با HMR برای توسعه راهاندازی میکند. jsProductionExecutableCompileSync باندل production را با minification و tree-shaking تولید میکند. فایل HTML نهایی که JavaScript کامپایلشده را متصل میکند، توسط پلاگین webpack تولید میشود و در build/dist قرار میگیرد.
// سرور توسعه را با HMR راهاندازی کن
./gradlew jsDevelopmentRun
// ساخت production با minification
./gradlew jsProductionExecutableCompileSync
// خروجی در build/dist/productionExecutable/
TypeScript — رقیب اصلی Kotlin/JS در حوزه JavaScript تایپشده است. هر دو زبان به JavaScript کامپایل میشوند و تایپاستاتیک را روی JS داینامیک اضافه میکنند. با این حال Kotlin/JS مزایایی را ارائه میدهد: null safety به طور پیشفرض، کلاسهای sealed، کوروتینها و یکپارچگی seamless با Kotlin Multiplatform. TypeScript به نوبه خود جامعه بزرگتری، کتابخانههای آماده بیشتری با انواع و اکوسیستم بالغتری دارد.
بهرهوری توسعه با Kotlin/JS میتواند برای تیمهایی که قبلاً از Kotlin در سایر بخشهای پروژه استفاده میکنند بیشتر باشد، زیرا نیاز به جابجایی بین زبانها نیست. TypeScript انتخاب محبوبتری برای پروژههای وب خالص باقی میماند که در آنها از Kotlin Multiplatform استفاده نمیشود. با این حال با رشد محبوبیت Compose Multiplatform برای وب، Kotlin/JS به عنوان جایگزینی برای React و Angular در حال کسب جایگاه است.
| ویژگی | Kotlin/JS | TypeScript |
|---|---|---|
| Null safety | پیشفرض | strictNullChecks اختیاری |
| کلاسهای sealed | پشتیبانی میشود | از طریق union types |
| کوروتینها | بومی | از طریق async/await |
| یکپارچگی KMM | کامل | وجود ندارد |
| اندازه جامعه | کوچک | بسیار بزرگ |
| انواع آماده برای کتابخانهها | محدود (DefinitelyTyped از طریق Dukat) | DefinitelyTyped (هزاران کتابخانه) |
انتخاب بین Kotlin/JS و TypeScript به زمینه پروژه بستگی دارد. اگر تیم قبلاً از Kotlin Multiplatform استفاده میکند یا قصد شروع دارد، Kotlin/JS انتخاب منطقی برای بخش frontend است. برای یک پروژه وب مجزا، TypeScript به دلیل در دسترس بودن انواع آماده برای کتابخانههای JavaScript و تعداد بیشتر توسعهدهندگان در بازار، راهحل عملیتری باقی میماند.
سوالات متداول
بله، JetBrains Kotlin Wrappers — wrapperهای type-safe Kotlin برای React، React Router و Redux ارائه میدهد. آنها امکان نوشتن کامپوننتهای React به زبان Kotlin با پشتیبانی کامل از hookها و DSL شبیه JSX را فراهم میکنند.
با فعال کردن generateTsDeclarations = true، Kotlin/JS فایلهای .d.ts را برای تمام APIهای عمومی تولید میکند. پروژههای TypeScript میتوانند ماژولهای Kotlin را با تایپبندی کامل مانند بستههای معمولی npm وارد کنند.
اندازه باندل به کتابخانههای استفادهشده بستگی دارد. حداقل برنامه Hello World حدود 300 کیلوبایت شامل Kotlin stdlib است. با React و Kotlin Wrappers اندازه به 400–600 کیلوبایت افزایش مییابد.
بله، از Kotlin/JS میتوان برای توسعه توابع serverless و ابزارهای کنسول تحت Node.js استفاده کرد. برای این کار در پیکربندی باید به جای js.browser از js.nodejs استفاده کرد.
Kotlin/Wasm — یک backend آزمایشی برای WebAssembly است، در حالی که Kotlin/JS کد JavaScript تولید میکند. Wasm عملکرد بالاتری ارائه میدهد اما دسترسی محدودی به DOM مرورگر دارد.
خلاصه
ما یک اپلیکیشن موبایل به صورت کلید در دست توسعه خواهیم داد
IT Sectr از سال 2017 برنامههای iOS و Android را برای استارتاپها و کسبوکارها ایجاد میکند. ما به شما مشاوره میدهیم و بهترین راهحل را پیشنهاد خواهیم کرد.