π Frontend development
Kotlin supports a wide selection of frontend frameworks across all platforms: mobile, desktop and web.
Please find below a glimpse of the possibilities that you can do right from IntelliJ:
- On the Desktop side
- Thanks to JVM support, Kotlin supports JavaFX (There was a Kotlin counterpart called tornadofx which is not maintained anymore).
- Compose Multiplatform brings Jetpack Compose to the desktop, the web and mobile.
- On the Web
- Ktor can use templates engines such as FreeMarker to create server pages.
- With KotlinJS, developers can create React, nodsjs, or vanilla JS Apps using Kotlin.
- Kotlin WASM compiles into Web Assembly. It can complement KotlinJS for computation intensive tasks.
- On Mobiles
- Android developers use the Jetpack Compose UI Framework or the legacy xml layouts. It is experimental on iOS.
Kotlin supports cross platform frontend development thanks to Kotlin MultiPlatform (KMP)
Kotlin Multiplatform (KMP)
"The Kotlin Multiplatform technology is designed to simplify the development of cross-platform projects. It reduces time spent writing and maintaining the same code for different platforms while retaining the flexibility and benefits of native programming." β
KMP relies on Kotlin native and other Kotlin features to help developers create projects that target multiple platforms using a common Kotlin code-base.
Many combinations of targets and use cases are possible:
- Full-Stack web apps: A project that contains a backend and a web app while sharing common logic.
- Multiplatform libraries
Kotlin/JS and Kotlin/WASM
- Kotlin/JS can also target the web and even use web frameworks (such as react) in Kolitn.
- Kotlin WASM is another possibility to target the web but this will generate WASM instead of pure JS code.
- It can be used for example to develop computation intensive libraries.
- Maybe we can do even more in the future with as all these technologies (Kotlin, WASM and Kotlin/WASM) evolve. - For example, WASI allows WASM to communicate with the operating system. - This means that me may see Kotlin/WASM project projects in the future that can target both the browser and the OS.
- Let's keep watching π.
π§ͺ Kotlin/WASM web app
- Let's create a Kotlin/WASM app. By cloning
git clone git@github.com:Kotlin/kotlin-wasm-examples.git
and opening the browser-example folder in your IDE.- To get up to date information on how to start a Kotlin/WASM project, please refer to the official documentation for kotlin/wasm.
- Open the project and run the
wasmJsBrowserRun
task. - The development server should start and you can open your WASM powered webapp on http://localhost:8080/
- β οΈ You may need to activate some flags on your browser for the app to work. If you see a blank page, please read the browser logs to check for the instructions.
- Please check the contents of src/wasmJsMain/kotlin/Simple.kt to understand how the page is coded.
- Next, let's check the generated wasm file which is available in build/js/packages/project_name/kotlin
- WASM being a binary format, we need to convert it first to text format.
- We can either install WABT (The WebAssembly Binary Toolkit or wabbit) and use the wasm2wattool
wasm2wat --enable-all -v .\kotlin-wasm-demo-wasm.wasm -o wasm.wat
, - or use an online converter such as this one
- β However, I couldn't get it to work (yet).
Kotlin/JS and Kotlin/WASM common points
Both Kotlin/WASM and Kotlin/JS IntelliJ work somewhat similarly.
- Both rely on the KMP plugin
- Kotlin/WASM is enabled by adding a
wasmjs
section in thebuild.gradle.kts
file, while Kotlin/JS is enabled by adding ajs
section. - The Kotlin code will compile to WASM and / or JS. Kotlin/JS generates only JS while Kotin/WASM generates both JS and WASM.
- In both cases, the entry point of the generated code is a JS file called module_name.js.
- The index.html in the resources folder loads the generated JS explained above (the one named module_name.js).
- The task
wasmBrowserDevelopmentRun
orjsWasmBrowserDevelopmentRun
run a local server that hosts both the index.html files and the generated JS and WASM files.
Compose multiplatform
"Compose Multiplatform simplifies and accelerates UI development for Desktop and Web applications, and allows extensive UI code sharing between Android, iOS, Desktop and Web. It's a modern toolkit for building native UI. Quickly bring your app to life with less code, powerful tools, and intuitive Kotlin APIs."
Button(
onClick = {
logger.info("Pressed!")
}
) {
Text("Hello $platform")
}
It is based on Android Jetpack Compose declarative UI approach ( which is similar also to iOS SwiftUI ) 1
Compose multiplatform vs Jetpack Compose
While very similar, Compose multiplatform is different from Jetpack Compose as the latter is only compatible with Android. Google provides a JetPack compose tutorial for Android development.
Compose HTML is not cross-platform
Compose HTML is UI a library targeting Kotlin/JS which is not compatible with Compose Multiplatform (it is a different API). For cross-platform UI development with Compose Multiplatform, compose Web is the choice.
π§ͺ Create a Compose multiplatform app
We'll create a multiplatform app using the official template. At the time of writing, this template does not include a compose web target.
- Please check that your environment is correctly setup as explained here.
- On Windows and Linux, we don't need to install iOS/macOS related tools but and we won't be able to run iOS/macOS targets.
- If we don't want to install Android Studio, we need at least to install the Android SDK either through the official installer or from the "Languages and Framework -> Android SDK" menu in the settings.
- Open the official template and either download a zip or use the "use this template" options on GitHub.
- Open the downloaded projet. You'll note that it contains these modules:
- a shared module (or subproject) that contains common code as well as
- and another module for earch targeted platform: androidApp, iOSApp and desktopApp (When web will be included in the template, we should also see a webApp project). These contain the source code of the apps itself (such as the main activity in Android, the
@main App
in iOS and the main function in desktopJVM) and well as platform specific resources that cannot be placed in the shared module. Some examples of such files are the AndroidManifest.xml for android and the info.plist in iOS.
- In order to run the desktopApp, open a terminal on the project root folder and launch this command:
./gradlew desktopApp:run
. - In order to run the Android App, the simplest way is to launch it from IntelliJ . It is also possible define a gradle task that installs the app on the device and issues a command to the device to launch it.
- In order to run the iOS App, the simplest way is to run it on the simulator using IntelliJ. In order to run it on a real device, the TramID needs to be defined as explained here
![Alt text](../../assets/kmp-compose-desktop.png =200x)
π§ͺ Playing with the Compose multiplatform API
Compose multiplatform is a component based declarative UI framework. Each component is called a Composable
and is defined as a function annotated with @Composable
.
In compose multiplatform, the main component (the component at the root of the App) is usually found in shared/src/commonMain/Kotlin/App.kt.
- Take a look at shared/src/commonMain/Kotlin/App.kt, run the app and try to understand how compose works.
- Let's create a new composable called
RandomNumberList
.
@Composable
fun RandomNumberList(){
// Generate a list of random numbers
val myRandomValues = List(5) { Random.nextInt(0, 30) }
// LazyColumn is a vertically scrolling list that renders items on demand
LazyColumn {
items(myRandomValues.size){
Text(text = "$it")
}
}
}
- Place this composable below
AnimatedVisibility
andButton
and run the app.
/*
Button(onClick ...
AnimatedVisibility(showImage) { ...
*/
RandomNumberList()
- Exercise: Make the "Hello, .." button switch between showing the list and and the image.