Kotlin/JS — nó là gì, trình biên dịch sang JavaScript và các tính năng

Tác giả: IT Sectr Đã đăng: 2026-06-05 Thời gian đọc: 7 phút

Kotlin/JS là trình biên dịch từ Kotlin sang JavaScript cho phép tạo các ứng dụng frontend và giao diện web bằng ngôn ngữ Kotlin. Không giống như TypeScript, Kotlin/JS cung cấp kiểu tĩnh nghiêm ngặt, hỗ trợ coroutine và tích hợp liền mạch với Kotlin Multiplatform. Kể từ Kotlin 1.8, trình biên dịch sử dụng backend dựa trên IR để tạo mã JavaScript được tối ưu hóa. Theo JetBrains, 2025, Kotlin/JS hỗ trợ tích hợp với hệ sinh thái NPM và TypeScript thông qua tạo tệp .d.ts tự động.

Những điểm chính

  • Kotlin/JS — trình biên dịch từ Kotlin sang JavaScript cho phát triển frontend và giao diện web.
  • Backend IR — biểu diễn trung gian được sử dụng để tạo mã JavaScript tối ưu hóa.
  • Tích hợp NPM — khả năng bao gồm các thư viện JavaScript thông qua phụ thuộc npm trong build.gradle.kts.
  • Tương thích TypeScript — tạo tệp .d.ts để tương tác an toàn giữa dự án TypeScript với mã Kotlin.
  • Tích hợp KMM — tái sử dụng mã Kotlin chung giữa ứng dụng di động và web.

Kotlin/JS là gì?

Kotlin/JS là một trong ba backend của trình biên dịch Kotlin (cùng với JVM và Native), được thiết kế để dịch mã Kotlin sang JavaScript. Được phát triển bởi JetBrains, Kotlin/JS cho phép viết ứng dụng web bằng ngôn ngữ có kiểu tĩnh nghiêm ngặt, đồng thời duy trì quyền truy cập vào hệ sinh thái thư viện JavaScript rộng lớn thông qua các khai báo bên ngoài. Kể từ bản phát hành ổn định đầu tiên trong Kotlin 1.3, trình biên dịch đã phát triển từ một backend thử nghiệm thành công cụ sẵn sàng sản xuất được sử dụng trong các dự án công nghiệp.

Mục đích chính của Kotlin/JS là phát triển frontend sử dụng Kotlin thay vì JavaScript hoặc TypeScript. Các nhà phát triển nhận được tất cả các tính năng của ngôn ngữ Kotlin: null safety, hàm mở rộng, lớp dữ liệu, coroutine và lớp sealed. Mã JavaScript được tạo có thể chạy trong bất kỳ trình duyệt hiện đại nào hoặc môi trường Node.js. Kotlin/JS đặc biệt có giá trị trong các dự án Kotlin Multiplatform, nơi mô-đun dùng chung (commonMain) có sẵn cho cả ứng dụng di động và web.

Hệ sinh thái Kotlin/JS bao gồm các framework để xây dựng giao diện người dùng. Compose Multiplatform cho web sử dụng Kotlin/JS làm backend mục tiêu, cho phép tạo các thành phần UI khai báo chạy trong trình duyệt. Các giải pháp thay thế bao gồm wrapper cho React — Kotlin Wrappers, cung cấp API an toàn về kiểu cho React, React Router và Redux.

Trình biên dịch Kotlin/JS hoạt động như thế nào

Biên dịch trong Kotlin/JS trải qua nhiều giai đoạn chuyển đổi. Mã Kotlin nguồn trước tiên được biên dịch thành biểu diễn trung gian (IR), sau đó được tối ưu hóa và cuối cùng mã JavaScript được tạo ra. Kể từ Kotlin 1.8, backend cũ (JsBackend dựa trên AST) đã được thay thế hoàn toàn bằng backend IR, cung cấp tối ưu hóa tốt hơn, kích thước mã đầu ra nhỏ hơn và tương thích với TypeScript.

Trước đây, Kotlin/JS sử dụng JsBackend, hoạt động trực tiếp với AST (Cây cú pháp trừu tượng). Cách tiếp cận này có những hạn chế: khó khăn trong việc hỗ trợ tối ưu hóa nền tảng, thiếu IR thống nhất cho tất cả các backend và không có khả năng tạo khai báo TypeScript. Việc chuyển đổi sang backend IR đã giải quyết những vấn đề này, thống nhất quá trình biên dịch trên cả ba backend Kotlin và mở đường cho các tối ưu hóa chéo giữa các backend.

Các chế độ biên dịch Kotlin/JS

Kotlin/JS hỗ trợ hai chế độ xây dựng xác định định dạng và tối ưu hóa mã đầu ra. Chế độ production sử dụng Webpack để đóng gói, rút gọn và loại bỏ mã chết. Chế độ development hỗ trợ Hot Module Replacement để lặp lại phát triển nhanh chóng. Việc chọn chế độ được cấu hình trong build.gradle.kts thông qua cấu hình js.target.

kotlin
kotlin {
    js {
        browser {
            webpackTask {
                outputFileName = "app.js"
            }
        }
        binaries.executable()
    }
}

Tích hợp với NPM và thư viện JavaScript

Tích hợp Kotlin/JS với hệ sinh thái NPM được thực hiện thông qua DSL đặc biệt trong build.gradle.kts. Nhà phát triển khai báo phụ thuộc npm trong cấu hình kotlin, chỉ định tên gói và phiên bản. Kotlin/JS tự động tải các gói qua trình quản lý gói npm hoặc yarn. Để đảm bảo truy cập an toàn về kiểu đến thư viện JavaScript, các khai báo bên ngoài được sử dụng để mô tả kiểu và hàm của thư viện cho trình biên dịch Kotlin.

Khai báo bên ngoài là các khai báo Kotlin được đánh dấu bằng từ khóa external. Chúng báo cho trình biên dịch biết rằng việc triển khai hàm hoặc lớp nằm trong mã JavaScript, không phải trong Kotlin. JetBrains cung cấp các bộ wrapper có sẵn cho các thư viện phổ biến trong Kotlin Wrappers, bao gồm React, React Router, Redux, Emotion và MUI. Đối với các thư viện không có wrapper sẵn, nhà phát triển có thể viết khai báo bên ngoài thủ công hoặc sử dụng trình tạo liên kết TypeScript Dukat.

kotlin
kotlin {
    js {
        browser { }
        npm {
            dependency("react", "18.3.1")
            dependency("react-dom", "18.3.1")
            devDependency("webpack", "5.92.0")
        }
    }
}

// Khai báo bên ngoài cho thư viện JavaScript
@JsModule("date-fns")
external fun formatDistance(
    date: Date, baseDate: Date
): String

Làm việc với tương thích TypeScript

TypeScript là một phần không thể thiếu của web hiện đại và Kotlin/JS đảm bảo tương thích với nó thông qua tạo tệp .d.ts. Khi đặt js.generateTsDeclarations = true, trình biên dịch tạo khai báo TypeScript cho tất cả các hàm và lớp công khai của Kotlin. Điều này cho phép các dự án TypeScript nhập mô-đun Kotlin với hỗ trợ kiểu đầy đủ. Việc tạo khai báo TypeScript chỉ hoạt động với backend IR và là một trong những lý do chính để di chuyển từ backend cũ.

Backend IR của Kotlin/JS và lợi ích

Backend IR (Intermediate Representation) là một backend thống nhất cho cả ba nền tảng Kotlin: JVM, JS và Native. Nó sử dụng một biểu diễn trung gian chung trải qua nhiều giai đoạn tối ưu hóa trước khi tạo mã mục tiêu. Đối với Kotlin/JS, backend IR trở thành bắt buộc từ Kotlin 1.8.0, thay thế backend cũ dựa trên AST đã được đánh dấu là không được dùng nữa.

Các lợi ích của backend IR cho Kotlin/JS bao gồm tối ưu hóa mã được cải thiện ở cấp độ IR, giảm kích thước bundle thông qua loại bỏ mã chết và tối ưu hóa inline, cũng như hỗ trợ khai báo TypeScript. Backend IR cũng đảm bảo xử lý chính xác các hàm inline, generic reified và hàm suspend khi dịch sang JavaScript, điều mà backend cũ gặp vấn đề.

Đặc điểmBackend cũ (AST)Backend IR
Khai báo TypeScriptKhông hỗ trợTự động tạo
Loại bỏ mã chếtHạn chếĐầy đủ, ở cấp IR
Hàm inlineVấn đề về tính đúng đắnXử lý chính xác
Generic reifiedKhông hỗ trợHỗ trợ
Kích thước bundleCơ bảnNhỏ hơn 20–30%

Ví dụ mã: thiết lập và phát triển

Một dự án Kotlin/JS đầy đủ bắt đầu bằng cấu hình build.gradle.kts. Plugin kotlin multiplatform cho phép thiết lập Kotlin/JS như một trong các nền tảng mục tiêu. Hãy xem ví dụ thiết lập cho ứng dụng web với React.

kotlin
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))
}

Sau khi cấu hình, có thể viết các thành phần React bằng Kotlin. Kotlin Wrappers cung cấp API an toàn về kiểu cho React, bao gồm các thành phần hàm, hook và cú pháp giống JSX thông qua trình xây dựng DSL. Ví dụ thành phần Counter minh họa làm việc với useState và trình xử lý sự kiện.

kotlin
@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)
    )
}

Xây dựng và triển khai

Việc xây dựng dự án Kotlin/JS được thực hiện thông qua các tác vụ Gradle. jsDevelopmentRun khởi động máy chủ phát triển Webpack với HMR để phát triển. jsProductionExecutableCompileSync tạo bundle production với rút gọn và loại bỏ mã chết. Tệp HTML cuối cùng bao gồm JavaScript đã biên dịch được tạo bởi plugin webpack và đặt trong build/dist.

kotlin
// Khởi động máy chủ phát triển với HMR
./gradlew jsDevelopmentRun

// Bản dựng production với rút gọn
./gradlew jsProductionExecutableCompileSync

// Đầu ra trong build/dist/productionExecutable/

Kotlin/JS so với TypeScript: so sánh

TypeScript là đối thủ cạnh tranh chính của Kotlin/JS trong lĩnh vực JavaScript có kiểu. Cả hai ngôn ngữ đều biên dịch sang JavaScript và thêm kiểu tĩnh trên nền JS động. Tuy nhiên, Kotlin/JS cung cấp một số lợi thế: null safety mặc định, lớp sealed, coroutine và tích hợp liền mạch với Kotlin Multiplatform. TypeScript, mặt khác, có cộng đồng lớn hơn, nhiều thư viện có sẵn với kiểu và hệ sinh thái trưởng thành hơn.

Năng suất phát triển với Kotlin/JS có thể cao hơn cho các nhóm đã sử dụng Kotlin trong các phần khác của dự án, vì không cần chuyển đổi ngôn ngữ. TypeScript vẫn là lựa chọn phổ biến hơn cho các dự án web thuần túy không sử dụng Kotlin Multiplatform. Tuy nhiên, với sự phổ biến ngày càng tăng của Compose Multiplatform cho web, Kotlin/JS đang giành được vị thế như một giải pháp thay thế cho React và Angular.

Đặc điểmKotlin/JSTypeScript
Null safetyMặc địnhstrictNullChecks tùy chọn
Lớp sealedHỗ trợQua union types
CoroutineTự nhiênQua async/await
Tích hợp KMMĐầy đủKhông có
Quy mô cộng đồngNhỏLớn
Kiểu có sẵn cho thư việnHạn chế (DefinitelyTyped qua Dukat)DefinitelyTyped (hàng nghìn thư viện)

Sự lựa chọn giữa Kotlin/JS và TypeScript phụ thuộc vào ngữ cảnh dự án. Nếu nhóm đã sử dụng Kotlin Multiplatform hoặc có kế hoạch bắt đầu, Kotlin/JS là lựa chọn hợp lý cho phần frontend. Đối với dự án web độc lập, TypeScript vẫn là giải pháp thực tế hơn nhờ sự sẵn có của kiểu cho thư viện JavaScript và số lượng nhà phát triển lớn hơn trên thị trường.

Câu hỏi thường gặp

Có thể sử dụng Kotlin/JS với React không?

Có, JetBrains cung cấp Kotlin Wrappers — wrapper Kotlin an toàn về kiểu cho React, React Router và Redux. Chúng cho phép viết thành phần React bằng Kotlin với hỗ trợ đầy đủ hook và DSL giống JSX.

Kotlin/JS hoạt động với dự án TypeScript như thế nào?

Khi bật generateTsDeclarations = true, Kotlin/JS tạo tệp .d.ts cho tất cả API công khai. Các dự án TypeScript có thể nhập mô-đun Kotlin với kiểu đầy đủ như gói npm thông thường.

Kích thước bundle của ứng dụng Kotlin/JS là bao nhiêu?

Kích thước bundle phụ thuộc vào thư viện sử dụng. Ứng dụng Hello World tối thiểu chiếm khoảng 300 KB bao gồm stdlib Kotlin. Với React và Kotlin Wrappers, kích thước tăng lên 400–600 KB.

Kotlin/JS có hỗ trợ môi trường Node.js không?

Có, Kotlin/JS có thể được sử dụng để phát triển hàm serverless và tiện ích console trong Node.js. Để làm điều này, hãy chỉ định js.nodejs thay vì js.browser trong cấu hình.

Kotlin/JS khác Kotlin/Wasm như thế nào?

Kotlin/Wasm là backend thử nghiệm cho WebAssembly, trong khi Kotlin/JS tạo mã JavaScript. Wasm cung cấp hiệu suất cao hơn nhưng truy cập hạn chế vào DOM trình duyệt.

Tổng kết

  • Kotlin/JS — trình biên dịch Kotlin sang JavaScript cho phát triển frontend với hỗ trợ coroutine, lớp sealed và null safety.
  • Backend IR đã thay thế backend cũ dựa trên AST, cung cấp tạo khai báo TypeScript và giảm kích thước bundle 20–30%.
  • Tích hợp NPM cho phép kết nối bất kỳ thư viện JavaScript nào thông qua khai báo bên ngoài và Kotlin Wrappers.
  • Tương thích TypeScript được thực hiện thông qua tạo tệp .d.ts tự động khi generateTsDeclarations = true.
  • Tích hợp KMM là lợi thế chính của Kotlin/JS so với TypeScript, cho phép tái sử dụng mã dùng chung với ứng dụng di động.
  • Đối với dự án web độc lập, TypeScript vẫn là lựa chọn thực tế hơn nhờ quy mô cộng đồng và sự sẵn có của kiểu.
  • Sử dụng Kotlin/JS cho phần frontend của dự án KMM hoặc khi phát triển với Compose Multiplatform cho web.

Chúng tôi sẽ phát triển ứng dụng di động chìa khóa trao tay

IT Sectr tạo các ứng dụng iOS và Android cho các công ty khởi nghiệp và doanh nghiệp từ năm 2017. Chúng tôi sẽ tư vấn và đề xuất giải pháp tốt nhất cho bạn.

Thảo luận dự án

Đọc thêm