Kotlin/JS es un compilador de Kotlin a JavaScript que permite crear aplicaciones frontend e interfaces web en el lenguaje Kotlin. A diferencia de TypeScript, Kotlin/JS proporciona tipado estático estricto, soporte para corrutinas e integración perfecta con Kotlin Multiplatform. Desde Kotlin 1.8, el compilador utiliza un backend basado en IR para generar código JavaScript optimizado. Según JetBrains, 2025, Kotlin/JS soporta integración con el ecosistema NPM y TypeScript mediante la generación automática de archivos .d.ts.
Puntos Clave
Kotlin/JS es uno de los tres backends del compilador Kotlin (junto con JVM y Native), diseñado para traducir código Kotlin a JavaScript. Desarrollado por JetBrains, Kotlin/JS permite escribir aplicaciones web en un lenguaje con tipado estático estricto, manteniendo el acceso al vasto ecosistema de bibliotecas JavaScript mediante declaraciones externas. Desde su primera versión estable en Kotlin 1.3, el compilador ha evolucionado de un backend experimental a una herramienta lista para producción utilizada en proyectos industriales.
El propósito principal de Kotlin/JS es el desarrollo frontend utilizando Kotlin en lugar de JavaScript o TypeScript. Los desarrolladores obtienen todas las características del lenguaje Kotlin: null safety, funciones de extensión, clases de datos, corrutinas y clases selladas. El código JavaScript generado puede ejecutarse en cualquier navegador moderno o en un entorno Node.js. Kotlin/JS es especialmente valioso en proyectos Kotlin Multiplatform, donde el módulo compartido (commonMain) está disponible tanto para aplicaciones móviles como web.
El ecosistema de Kotlin/JS incluye frameworks para construir interfaces de usuario. Compose Multiplatform para web utiliza Kotlin/JS como backend objetivo, permitiendo crear componentes de interfaz declarativos que se ejecutan en el navegador. Las soluciones alternativas incluyen envoltorios para React — Kotlin Wrappers, que proporcionan una API type-safe para React, React Router y Redux.
La compilación en Kotlin/JS pasa por varias etapas de transformación. El código Kotlin fuente primero se compila en una representación intermedia (IR), luego se optimiza y finalmente se genera código JavaScript. Desde Kotlin 1.8, el antiguo backend (JsBackend basado en AST) ha sido reemplazado completamente por el backend IR, que proporciona mejor optimización, menor tamaño de código de salida y compatibilidad con TypeScript.
Anteriormente, Kotlin/JS utilizaba JsBackend, que trabajaba directamente con el AST (Árbol de Sintaxis Abstracta). Este enfoque tenía limitaciones: dificultad para soportar optimizaciones de plataforma, falta de un IR unificado para todos los backends e incapacidad para generar declaraciones TypeScript. La transición al backend IR resolvió estos problemas, unificando la compilación en los tres backends de Kotlin y abriendo el camino para optimizaciones cruzadas entre backends.
Kotlin/JS soporta dos modos de compilación que determinan el formato y la optimización del código de salida. El modo producción utiliza Webpack para empaquetado, minificación y tree-shaking. El modo desarrollo soporta Hot Module Replacement para iteración rápida durante el desarrollo. La selección del modo se configura en build.gradle.kts mediante la configuración js.target.
kotlin {
js {
browser {
webpackTask {
outputFileName = "app.js"
}
}
binaries.executable()
}
}
La integración de Kotlin/JS con el ecosistema NPM se implementa mediante un DSL especial en build.gradle.kts. El desarrollador declara dependencias npm en la configuración kotlin, especificando el nombre del paquete y la versión. Kotlin/JS obtiene automáticamente los paquetes a través del gestor de paquetes npm o yarn. Para garantizar el acceso type-safe a las bibliotecas JavaScript, se utilizan declaraciones externas que describen los tipos y funciones de la biblioteca para el compilador Kotlin.
Las declaraciones externas son declaraciones Kotlin marcadas con la palabra clave external. Indican al compilador que la implementación de la función o clase está en código JavaScript, no en Kotlin. JetBrains proporciona conjuntos de envoltorios listos para bibliotecas populares como parte de Kotlin Wrappers, incluyendo React, React Router, Redux, Emotion y MUI. Para bibliotecas sin envoltorios listos, el desarrollador puede escribir declaraciones externas manualmente o usar el generador de enlaces TypeScript Dukat.
kotlin {
js {
browser { }
npm {
dependency("react", "18.3.1")
dependency("react-dom", "18.3.1")
devDependency("webpack", "5.92.0")
}
}
}
// Declaración externa para biblioteca de JavaScript
@JsModule("date-fns")
external fun formatDistance(
date: Date, baseDate: Date
): String
TypeScript es una parte integral de la web moderna, y Kotlin/JS garantiza la compatibilidad con él mediante la generación de archivos .d.ts. Al configurar js.generateTsDeclarations = true, el compilador crea declaraciones TypeScript para todas las funciones y clases públicas de Kotlin. Esto permite que los proyectos TypeScript importen módulos Kotlin con soporte completo de tipos. La generación de declaraciones TypeScript solo funciona con el backend IR y es una de las razones clave para migrar desde el backend antiguo.
El backend IR (Intermediate Representation) es un backend unificado para las tres plataformas Kotlin: JVM, JS y Native. Utiliza una representación intermedia común que pasa por varias etapas de optimización antes de generar el código objetivo. Para Kotlin/JS, el backend IR se volvió obligatorio a partir de Kotlin 1.8.0, reemplazando el antiguo backend basado en AST, que fue marcado como obsoleto.
Las ventajas del backend IR para Kotlin/JS incluyen optimización de código mejorada a nivel de IR, reducción del tamaño del bundle mediante eliminación de código muerto y optimizaciones inline, así como soporte para declaraciones TypeScript. El backend IR también garantiza el manejo correcto de funciones inline, genéricos reified y funciones suspend al traducir a JavaScript, lo que era problemático en el backend antiguo.
| Característica | Backend antiguo (AST) | Backend IR |
|---|---|---|
| Declaraciones TypeScript | No soportadas | Generadas automáticamente |
| Eliminación de código muerto | Limitada | Completa, a nivel de IR |
| Funciones inline | Problemas de corrección | Manejo correcto |
| Genéricos reified | No soportados | Soportados |
| Tamaño del bundle | Base | 20–30% más pequeño |
Un proyecto completo de Kotlin/JS comienza con la configuración de build.gradle.kts. El plugin kotlin multiplatform permite configurar Kotlin/JS como una de las plataformas objetivo. Veamos un ejemplo de configuración para una aplicación web con 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))
}
Después de la configuración, se pueden escribir componentes React en Kotlin. Kotlin Wrappers proporcionan una API type-safe para React, incluyendo componentes funcionales, hooks y sintaxis similar a JSX mediante constructores DSL. El ejemplo del componente Counter demuestra el trabajo con useState y manejadores de eventos.
@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)
)
}
La compilación de un proyecto Kotlin/JS se realiza mediante tareas de Gradle. jsDevelopmentRun inicia el servidor de desarrollo Webpack con HMR para desarrollo. jsProductionExecutableCompileSync genera un bundle de producción con minificación y tree-shaking. El archivo HTML final que incluye el JavaScript compilado es generado por el plugin webpack y se coloca en build/dist.
// Iniciar servidor de desarrollo con HMR
./gradlew jsDevelopmentRun
// Compilación de producción con minificación
./gradlew jsProductionExecutableCompileSync
// Salida en build/dist/productionExecutable/
TypeScript es el principal competidor de Kotlin/JS en el ámbito del JavaScript tipado. Ambos lenguajes se compilan a JavaScript y añaden tipado estático sobre el JS dinámico. Sin embargo, Kotlin/JS ofrece varias ventajas: null safety por defecto, clases selladas, corrutinas e integración perfecta con Kotlin Multiplatform. TypeScript, por su parte, tiene una comunidad más grande, más bibliotecas listas con tipos y un ecosistema más maduro.
La productividad de desarrollo con Kotlin/JS puede ser mayor para equipos que ya usan Kotlin en otras partes del proyecto, ya que no requiere cambiar de lenguaje. TypeScript sigue siendo la opción más popular para proyectos web puros donde no se utiliza Kotlin Multiplatform. Sin embargo, con la creciente popularidad de Compose Multiplatform para web, Kotlin/JS está ganando terreno como alternativa a React y Angular.
| Característica | Kotlin/JS | TypeScript |
|---|---|---|
| Null safety | Por defecto | strictNullChecks opcional |
| Clases selladas | Soportadas | Mediante union types |
| Corrutinas | Nativas | Mediante async/await |
| Integración KMM | Completa | Ninguna |
| Tamaño de la comunidad | Pequeña | Enorme |
| Tipos listos para bibliotecas | Limitados (DefinitelyTyped vía Dukat) | DefinitelyTyped (miles de bibliotecas) |
La elección entre Kotlin/JS y TypeScript depende del contexto del proyecto. Si el equipo ya utiliza Kotlin Multiplatform o planea empezar, Kotlin/JS es una opción lógica para la parte frontend. Para un proyecto web aislado, TypeScript sigue siendo una solución más pragmática debido a la disponibilidad de tipos listos para bibliotecas JavaScript y un mayor número de desarrolladores en el mercado.
Preguntas Frecuentes
Sí, JetBrains proporciona Kotlin Wrappers — envoltorios Kotlin type-safe para React, React Router y Redux. Permiten escribir componentes React en Kotlin con soporte completo para hooks y DSL similar a JSX.
Al habilitar generateTsDeclarations = true, Kotlin/JS genera archivos .d.ts para todas las API públicas. Los proyectos TypeScript pueden importar módulos Kotlin con tipado completo como paquetes npm regulares.
El tamaño del bundle depende de las bibliotecas utilizadas. Una aplicación mínima Hello World ocupa aproximadamente 300 KB incluyendo la stdlib de Kotlin. Con React y Kotlin Wrappers, el tamaño aumenta a 400–600 KB.
Sí, Kotlin/JS se puede utilizar para desarrollar funciones serverless y utilidades de consola en Node.js. Para ello, se debe especificar js.nodejs en lugar de js.browser en la configuración.
Kotlin/Wasm es un backend experimental para WebAssembly, mientras que Kotlin/JS genera código JavaScript. Wasm proporciona mayor rendimiento pero tiene acceso limitado al DOM del navegador.
Resumen
Desarrollaremos una aplicación móvil llave en mano
IT Sectr crea aplicaciones para iOS y Android para startups y empresas desde 2017. Le asesoraremos y le propondremos la mejor solución.
Lea también