Kotlin Multiplatform: qué es, shared module y expect/actual

Autor: IT Sectr Publicado: 2026-02-11 Tiempo de lectura: 11 min

Kotlin Multiplatform (KMP) es una tecnología de JetBrains que compila código Kotlin compartido para iOS, Android, Web y Desktop. A diferencia de Flutter y React Native, KMP no reemplaza las UI nativas — la lógica compartida se extrae en un shared module, mientras que la interfaz de cada aplicación sigue siendo nativa. Kotlin Multiplatform documentation — la referencia principal para configurar módulos y el mecanismo expect/actual.

Puntos clave

  • KMP — lógica compartida en Kotlin con expect/actual para APIs de plataforma sin reemplazar la UI nativa
  • Shared module — un módulo Gradle con código de red, base de datos, validación y lógica de negocio para todas las plataformas
  • Expect/actual — mecanismo para declarar API de plataforma en código compartido con implementación para cada destino
  • Integración iOS — el shared module se compila en un framework de Apple mediante Kotlin/Native
  • KMP vs KMM — Kotlin Multiplatform Mobile (enfoque móvil) ahora es parte de Kotlin Multiplatform

¿Qué es Kotlin Multiplatform?

Kotlin Multiplatform es una tecnología de compilación cruzada que permite escribir código compartido en Kotlin y compilarlo para diferentes plataformas: JVM (Android), LLVM (iOS, macOS, watchOS), JavaScript (Web) y binarios nativos (Linux, Windows). KMP no es un framework de UI — resuelve el problema de reutilizar la lógica de negocio, no las interfaces.

La arquitectura KMP se construye alrededor de un shared module — un módulo Gradle que contiene commonMain con código independiente de la plataforma y source sets para cada destino (androidMain, iosMain, desktopMain). Según datos de JetBrains para 2025, más del 40% de los nuevos proyectos Kotlin utilizan KMP para compartir código entre plataformas.

Kotlin Multiplatform Mobile (KMM) — el nombre anterior para el escenario móvil iOS+Android. Desde Kotlin 2.1+, el término KMM ha sido reemplazado por Kotlin Multiplatform, ya que la tecnología ha superado el desarrollo móvil. Netflix, McDonald's y VMware utilizan KMP en producción para compartir código entre aplicaciones móviles.

Mecanismo expect/actual: arquitectura

Expect/actual — el mecanismo clave de KMP para trabajar con código específico de plataforma. En commonMain se declara una declaración expect (función, clase, propiedad), y en cada source set específico de plataforma (androidMain, iosMain) se proporciona una implementación actual. El compilador verifica que para cada expect exista un actual en cada plataforma destino.

kotlin
// commonMain — declaración de API de plataforma
expect fun getPlatformName(): String

expect class PlatformContext(val appVersion: String)

// androidMain — actual para Android
actual fun getPlatformName(): String = "Android \${Build.VERSION.SDK_INT}"

// iosMain — actual para iOS
actual fun getPlatformName(): String =
    UIDevice.currentDevice.systemName

La jerarquía de source sets en KMP permite crear niveles intermedios: por ejemplo, iosArm64Main (dispositivos iOS físicos) e iosSimulatorArm64Main (simulador) con iosMain compartido. El código de commonMain está disponible para todas las plataformas, mientras que el código de iosMain solo está disponible para destinos iOS. Esto reduce la duplicación cuando la implementación difiere no para cada plataforma sino para un grupo de plataformas.

En la práctica, expect/actual se utiliza para: acceder al almacenamiento local (SharedPreferences vs NSUserDefaults), redes (HttpEngine por plataforma), acceso al sistema de archivos, criptografía y análisis. JetBrains recomienda minimizar el número de declaraciones expect/actual y mover la mayor cantidad de código posible a commonMain.

Shared module: estructura y Gradle

Shared module — un módulo Gradle estándar con el plugin org.jetbrains.kotlin.multiplatform. Contiene código compartido en src/commonMain/kotlin/ e implementaciones específicas de plataforma en src/androidMain/kotlin/ y src/iosMain/kotlin/. Un proyecto KMP también incluye androidApp y iosApp, que dependen del shared module.

kotlin
// build.gradle.kts — shared module
plugins {
    kotlin("multiplatform")
    id("com.android.library")
}

kotlin {
    androidTarget()
    
    listOf(
        iosX64(),
        iosArm64(),
        iosSimulatorArm64()
    ).forEach {
        it.binaries.framework {
            baseName = "shared"
            isStatic = true
        }
    }

    sourceSets {
        val commonMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-core:3.1.0")
                implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.7.3")
            }
        }
        val androidMain by getting {
            dependencies {
                implementation("io.ktor:ktor-client-okhttp:3.1.0")
            }
        }
        val iosMain by creating {
            dependencies {
                implementation("io.ktor:ktor-client-darwin:3.1.0")
            }
        }
    }
}

La configuración de Gradle para KMP requiere la declaración explícita de destinos iOS — x64 (simulador Intel), arm64 (dispositivos físicos) y simulatorArm64 (simulador Apple Silicon). Se genera un framework de Apple separado para cada destino. El plugin kotlin("multiplatform") configura automáticamente la compilación para JVM y LLVM según los destinos declarados.

Ktor y kotlinx.serialization — bibliotecas KMP estándar que admiten código compartido. Ktor proporciona un cliente HTTP con motores para cada plataforma (OkHttp para Android, Darwin para iOS). kotlinx.serialization funciona en todas las plataformas sin expect/actual gracias a su implementación multiplataforma en commonMain.

Integración con iOS mediante Kotlin/Native

Kotlin/Native — un compilador de Kotlin para código nativo mediante LLVM. Para iOS, el shared module se compila en un framework de Apple (.framework) que se conecta a través de Xcode. La llamada al código compartido desde Swift/Objective-C ocurre a través de los encabezados Objective-C generados, por lo que la API del shared module debe ser compatible con Objective-C.

Limitaciones de la integración con iOS: las colecciones de Kotlin (List, Map) se convierten en NSArray/NSDictionary. Las funciones con parámetros predeterminados no se exportan — se necesitan sobrecargas. Para las funciones suspend, se generan métodos basados en callbacks con @ObjCName y soporte async/await a partir de Kotlin 2.0+.

swift
// Aplicación iOS: llamada al shared module desde Swift
import shared

class ViewModel: ObservableObject {
    let repository = UserRepository()
    
    func loadUsers() {
        repository.fetchUsers(completionHandler: { result, error in
            if let users = result as? [User] {
                print("Users: \(users.count)")
            }
        })
    }
}

La integración del shared module en Xcode se realiza mediante embed-and-framework — el .xcframework generado se añade al proyecto Xcode. El plugin de Gradle puede actualizar automáticamente el framework durante la compilación mediante embedAndSignAppleFrameworkForXcode. Para pruebas en el simulador, es suficiente un binario iosSimulatorArm64 o iosX64.

KMP vs Flutter vs React Native

La elección entre KMP, Flutter y React Native depende de la prioridad: reutilización de código o multiplataforma completa. KMP proporciona UI nativa en cada plataforma pero requiere dos bases de código para la interfaz. Flutter y React Native utilizan una sola UI pero sacrifican la nati­vidad.

CaracterísticaKMPFlutterReact Native
Framework de UINativo (Android XML/Jetpack Compose + SwiftUI)Dart + renderizador Skia propioReact + componentes nativos
Código compartidoLógica de negocio, red, BD, validación100% excepto plugins nativos100% excepto módulos nativos
RendimientoNativo (sin capa intermedia)Alto (Skia Engine)Medio (JSI Bridge)
Soporte iOSKotlin/Native (excelente)ExcelenteBueno
Barrera de entradaMedia (Kotlin + plataformas nativas)Baja (un lenguaje + una UI)Baja (JS/TS + React)

Cuándo elegir KMP: el proyecto requiere UI de alto rendimiento (juegos, mapas, animaciones), es necesario reutilizar código nativo existente, el equipo ya conoce Kotlin y las plataformas nativas. Cuándo elegir Flutter/RN: MVP o startup con presupuesto limitado, equipo de un solo perfil, la UI no requiere personalización nativa profunda.

Herramientas y bibliotecas KMP

El ecosistema de herramientas KMP incluye bibliotecas para todas las capas de la aplicación: redes (Ktor), serialización (kotlinx.serialization), base de datos (SQLDelight), navegación (Decompose), DI (Koin) y almacenamiento de datos (multiplatform-settings). JetBrains admite Compose Multiplatform — un framework de UI en Kotlin que funciona en todas las plataformas.

kotlin
// Repositorio KMP con SQLDelight + Ktor
class UserRepository(
    private val httpClient: HttpClient,
    private val db: AppDatabase
) {
    suspend fun syncUsers(): List<User> {
        val remote = httpClient.get("https://api.example.com/users")
            .body<List<UserDto>>()
        
        db.userQueries.replaceAll(remote.map { it.toDomain() })
        
        return db.userQueries.selectAll().executeAsList()
    }
}

Compose Multiplatform — un framework de UI para KMP basado en Jetpack Compose. Permite escribir interfaces en Kotlin para Android, iOS, Desktop y Web. En 2025, Compose Multiplatform alcanzó el estado estable para Android y Desktop; el destino iOS está en beta. Para proyectos de producción con UI nativa, la ventaja de KMP sigue siendo la diferencia clave con Flutter.

Preguntas frecuentes

¿En qué se diferencia Kotlin Multiplatform de Kotlin Multiplatform Mobile?

KMM — el escenario móvil de KMP para iOS y Android. Desde Kotlin 2.1+, JetBrains combinó ambos términos en Kotlin Multiplatform, ya que la tecnología admite no solo plataformas móviles sino también Desktop y Web. Los proyectos KMM continúan funcionando, pero ahora son parte del KMP general.

¿Se puede usar KMP con SwiftUI?

Sí. KMP se compila en un framework de Apple mediante Kotlin/Native con encabezados Objective-C. SwiftUI importa este framework como cualquier biblioteca normal. El shared module exporta clases y funciones de Kotlin que se llaman desde Swift con algunas limitaciones (por ejemplo, las colecciones de Kotlin se convierten en tipos de Foundation).

¿Cómo probar el shared module en iOS?

En iOS, el shared module se prueba mediante pruebas de Kotlin/Native en el source set iosTest. Para pruebas de UI se utiliza XCTest en Xcode con el framework importado. Las pruebas de Kotlin se escriben en commonTest con kotlin.test y se ejecutan en el simulador de iOS mediante la tarea de Gradle iosSimulatorArm64Test.

¿Qué bibliotecas están disponibles en KMP?

Principales bibliotecas KMP: Ktor (redes), kotlinx.serialization (JSON), SQLDelight (BD), Koin (DI), Decompose (navegación), multiplatform-settings (SharedPreferences/NSUserDefaults), Apollo GraphQL, Firebase (mediante KMP-NativeCoroutines). Compose Multiplatform proporciona UI para todas las plataformas.

¿KMP es compatible con Gradle 8?

Sí. KMP es totalmente compatible con Gradle 8.5+. A partir de Kotlin 2.1, los plugins oficiales admiten Gradle 8. La configuración mediante build.gradle.kts con kotlin("multiplatform") requiere Gradle 7.6+, pero se recomienda la versión 8.5 para un rendimiento óptimo de compilación.

Resumen

  • Kotlin Multiplatform — tecnología multiplataforma de JetBrains para código compartido sin reemplazar la UI nativa
  • Expect/actual — mecanismo para declarar APIs de plataforma en commonMain con implementaciones para cada destino
  • Shared module — módulo Gradle con commonMain y source sets específicos de plataforma (androidMain, iosMain)
  • Kotlin/Native compila el shared module en un framework de Apple invocable desde Swift y Objective-C
  • KMP vs Flutter/RN — reutilización de lógica + UI nativa frente a base de código única y UI
  • Compose Multiplatform — framework de UI en Kotlin para Android, iOS, Desktop y Web
  • Ecosistema — Ktor, SQLDelight, Koin, kotlinx.serialization, Decompose para todas las capas de la aplicación

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.

Discutir el proyecto

Lea también