Kotlin/JSは、Kotlin言語でフロントエンドアプリケーションやWebインターフェースを作成できるKotlinからJavaScriptへのコンパイラです。TypeScriptとは異なり、Kotlin/JSは厳格な静的型付け、コルーチンのサポート、Kotlin Multiplatformとのシームレスな統合を提供します。Kotlin 1.8以降、コンパイラはIRベースのバックエンドを使用して最適化されたJavaScriptコードを生成します。JetBrains、2025によると、Kotlin/JSは自動的な.d.tsファイル生成を通じてNPMエコシステムおよびTypeScriptとの統合をサポートしています。
重要ポイント
Kotlin/JSは、Kotlinコンパイラの3つのバックエンドの1つ(JVMおよびNativeと並んで)で、KotlinコードをJavaScriptに変換するために設計されています。JetBrainsによって開発されたKotlin/JSは、外部宣言を通じてJavaScriptライブラリの広大なエコシステムへのアクセスを維持しながら、厳格な静的型付け言語でWebアプリケーションを記述することを可能にします。Kotlin 1.3での最初の安定版リリース以来、コンパイラは実験的なバックエンドから産業プロジェクトで使用される本番環境対応ツールへと進化しました。
Kotlin/JSの主な目的は、JavaScriptやTypeScriptの代わりにKotlinを使用したフロントエンド開発です。開発者はKotlin言語のすべての機能(null安全性、拡張関数、データクラス、コルーチン、sealedクラス)を利用できます。生成されたJavaScriptコードは、任意の最新ブラウザまたはNode.js環境で実行できます。Kotlin/JSは、共有モジュール(commonMain)がモバイルアプリケーションとWebアプリケーションの両方で利用できるKotlin Multiplatformプロジェクトで特に価値があります。
Kotlin/JSエコシステムには、ユーザーインターフェースを構築するためのフレームワークが含まれています。Web向けのCompose Multiplatformは、ターゲットバックエンドとしてKotlin/JSを使用し、ブラウザで動作する宣言型UIコンポーネントを作成できます。代替ソリューションには、React用のラッパーであるKotlin Wrappersが含まれ、React、React Router、Redux向けの型安全なAPIを提供します。
コンパイルはKotlin/JSでいくつかの変換段階を経ます。ソースのKotlinコードはまず中間表現(IR)にコンパイルされ、次に最適化され、最後にJavaScriptコードが生成されます。Kotlin 1.8以降、古いバックエンド(ASTベースのJsBackend)は完全にIRバックエンドに置き換えられ、より良い最適化、より小さな出力コードサイズ、TypeScript互換性を提供します。
以前は、Kotlin/JSはAST(抽象構文木)で直接動作するJsBackendを使用していました。このアプローチには制限がありました:プラットフォーム最適化のサポートが困難、すべてのバックエンドに統一されたIRがない、TypeScript宣言を生成できないなどです。IRバックエンドへの移行によりこれらの問題が解決され、3つのKotlinバックエンド全体でのコンパイルが統一され、クロスバックエンド最適化への道が開かれました。
Kotlin/JSは、出力コードの形式と最適化を決定する2つのビルドモードをサポートしています。プロダクションモードは、バンドル、ミニフィケーション、ツリーシェイキングにWebpackを使用します。開発モードは、高速な開発イテレーションのためにHot Module Replacementをサポートしています。モードの選択は、js.target設定を通じてbuild.gradle.ktsで構成されます。
kotlin {
js {
browser {
webpackTask {
outputFileName = "app.js"
}
}
binaries.executable()
}
}
Kotlin/JSとNPMエコシステムの統合は、build.gradle.ktsの特別なDSLを通じて実装されています。開発者はkotlin設定でnpm依存関係を宣言し、パッケージ名とバージョンを指定します。Kotlin/JSはnpmまたはyarnパッケージマネージャーを通じて自動的にパッケージを取得します。JavaScriptライブラリへの型安全なアクセスを確保するために、Kotlinコンパイラに対してライブラリの型と関数を記述する外部宣言が使用されます。
外部宣言は、externalキーワードでマークされたKotlin宣言です。これらは、関数やクラスの実装がKotlinではなくJavaScriptコードにあることをコンパイラに伝えます。JetBrainsは、Kotlin Wrappersの一部として人気のあるライブラリ向けの既製ラッパーセットを提供しており、React、React Router、Redux、Emotion、MUIが含まれます。既製のラッパーがないライブラリについては、開発者が手動で外部宣言を記述するか、Dukat TypeScriptバインディングジェネレーターを使用できます。
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は現代のWebに不可欠な要素であり、Kotlin/JSは.d.tsファイルの生成を通じてTypeScriptとの互換性を確保しています。js.generateTsDeclarations = trueに設定すると、コンパイラはすべての公開Kotlin関数とクラスのTypeScript宣言を作成します。これにより、TypeScriptプロジェクトは完全な型サポートでKotlinモジュールをインポートできます。TypeScript宣言の生成はIRバックエンドでのみ機能し、古いバックエンドからの移行の主な理由の1つです。
IRバックエンド(Intermediate Representation)は、3つのKotlinプラットフォーム(JVM、JS、Native)すべてのための統一バックエンドです。ターゲットコードを生成する前に、いくつかの最適化段階を経る共通の中間表現を使用します。Kotlin/JSでは、IRバックエンドはKotlin 1.8.0以降必須となり、非推奨とマークされた古いASTベースのバックエンドを置き換えました。
Kotlin/JS向けIRバックエンドの利点には、IRレベルでの改善されたコード最適化、デッドコード除去とインライン最適化によるバンドルサイズの削減、TypeScript宣言のサポートが含まれます。IRバックエンドはまた、JavaScriptへの変換時におけるインライン関数、reifiedジェネリクス、suspend関数の正しい処理を保証します。これは古いバックエンドでは問題がありました。
| 特徴 | 古いバックエンド(AST) | IRバックエンド |
|---|---|---|
| TypeScript宣言 | 未サポート | 自動生成 |
| デッドコード除去 | 限定的 | 完全、IRレベル |
| インライン関数 | 正確性の問題 | 正しい処理 |
| Reifiedジェネリクス | 未サポート | サポート |
| バンドルサイズ | ベース | 20~30%削減 |
本格的なKotlin/JSプロジェクトは、build.gradle.ktsの設定から始まります。kotlin multiplatformプラグインを使用すると、Kotlin/JSをターゲットプラットフォームの1つとして設定できます。Reactを使用したWebアプリケーションの設定例を見てみましょう。
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))
}
設定後、KotlinでReactコンポーネントを記述できます。Kotlin Wrappersは、関数コンポーネント、フック、DSLビルダーによるJSXライクな構文を含む、React向けの型安全なAPIを提供します。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は、開発用にHMR対応のWebpack開発サーバーを起動します。jsProductionExecutableCompileSyncは、ミニフィケーションとツリーシェイキングを行ったプロダクションバンドルを生成します。コンパイルされたJavaScriptを含む最終的なHTMLファイルは、webpackプラグインによって生成され、build/distに配置されます。
// HMRで開発サーバーを起動
./gradlew jsDevelopmentRun
// ミニフィケーションを含むプロダクションビルド
./gradlew jsProductionExecutableCompileSync
// build/dist/productionExecutable/に出力
TypeScriptは、型付きJavaScriptの領域におけるKotlin/JSの主要な競合です。両方の言語はJavaScriptにコンパイルされ、動的なJSの上に静的型付けを追加します。しかし、Kotlin/JSはいくつかの利点を提供します:デフォルトのnull安全性、sealedクラス、コルーチン、Kotlin Multiplatformとのシームレスな統合。一方、TypeScriptはより大きなコミュニティ、型付きの既製ライブラリ、より成熟したエコシステムを持っています。
Kotlin/JSでの開発生産性は、プロジェクトの他の部分ですでにKotlinを使用しているチームにとっては高い可能性があります。なぜなら言語の切り替えが不要だからです。TypeScriptは、Kotlin Multiplatformを使用しない純粋なWebプロジェクトではより一般的な選択肢のままです。しかし、Web向けCompose Multiplatformの人気が高まるにつれて、Kotlin/JSはReactやAngularの代替として地位を確立しつつあります。
| 特徴 | Kotlin/JS | TypeScript |
|---|---|---|
| Null安全性 | デフォルト | strictNullChecksはオプション |
| Sealedクラス | サポート | ユニオン型による |
| コルーチン | ネイティブ | async/awaitによる |
| KMM統合 | 完全 | なし |
| コミュニティ規模 | 小規模 | 巨大 |
| ライブラリの型対応 | 限定的(Dukat経由のDefinitelyTyped) | DefinitelyTyped(数千のライブラリ) |
Kotlin/JSとTypeScriptの選択は、プロジェクトのコンテキストによります。チームがすでにKotlin Multiplatformを使用しているか、開始を計画している場合、Kotlin/JSはフロントエンド部分の論理的な選択です。独立したWebプロジェクトの場合、TypeScriptはJavaScriptライブラリの型の可用性と市場の開発者数の多さから、より実用的なソリューションであり続けています。
よくある質問
はい、JetBrainsはKotlin Wrappersを提供しています。これはReact、React Router、Redux向けの型安全なKotlinラッパーです。フックとJSXライクなDSLを完全にサポートしながら、KotlinでReactコンポーネントを記述できます。
generateTsDeclarations = trueを有効にすると、Kotlin/JSはすべての公開APIの.d.tsファイルを生成します。TypeScriptプロジェクトは、通常のnpmパッケージとして完全な型付けでKotlinモジュールをインポートできます。
バンドルサイズは使用するライブラリによって異なります。最小のHello Worldアプリケーションは、Kotlin stdlibを含めて約300 KBです。ReactとKotlin Wrappersを使用すると、サイズは400~600 KBに増加します。
はい、Kotlin/JSはNode.jsでのサーバーレス関数やコンソールユーティリティの開発に使用できます。これを行うには、設定でjs.browserの代わりにjs.nodejsを指定します。
Kotlin/WasmはWebAssembly向けの実験的なバックエンドであり、Kotlin/JSはJavaScriptコードを生成します。Wasmはより高いパフォーマンスを提供しますが、ブラウザのDOMへのアクセスが制限されています。
まとめ
ターンキー方式のモバイルアプリケーションを開発します
IT Sectrは2017年からスタートアップや企業向けにiOS・Androidアプリケーションを開発しています。私たちがご相談に乗り、最適なソリューションをご提案します。