Márton Braun
Developer Advocate
Blazing Fast UI Development with
Slide 2
Slide 2 text
Demo
Slide 3
Slide 3 text
Setup
!// build.gradle.kts
plugins {
id("org.jetbrains.compose.hot-reload") version "1.0.0-alpha11"
}
Slide 4
Slide 4 text
Setup
!// build.gradle.kts
plugins {
id("org.jetbrains.compose.hot-reload") version "1.0.0-alpha11"
}
!// settings.gradle.kts
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
Slide 5
Slide 5 text
Setup
!// build.gradle.kts
plugins {
id("org.jetbrains.compose.hot-reload") version "1.0.0-alpha11"
}
!// settings.gradle.kts
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
!// Default in Kotlin 2.2.0
composeCompiler {
featureFlags.add(ComposeFeatureFlag.OptimizeNonSkippingGroups)
}
Slide 6
Slide 6 text
Setup
!// build.gradle.kts
plugins {
id("org.jetbrains.compose.hot-reload") version "1.0.0-alpha11"
}
!// settings.gradle.kts
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
!// Default in Kotlin 2.2.0
composeCompiler {
featureFlags.add(ComposeFeatureFlag.OptimizeNonSkippingGroups)
}
Slide 7
Slide 7 text
How does it work?
Your app’s code
Java Runtime
Gradle
Slide 8
Slide 8 text
How does it work?
Your app’s code
JetBrains Runtime
Gradle
Slide 9
Slide 9 text
Setup
!// build.gradle.kts
plugins {
id("org.jetbrains.compose.hot-reload") version "1.0.0-alpha11"
}
!// settings.gradle.kts
plugins {
id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}
!// Default in Kotlin 2.2.0
composeCompiler {
featureFlags.add(ComposeFeatureFlag.OptimizeNonSkippingGroups)
}
Slide 10
Slide 10 text
How does it work?
Your app’s code
JetBrains Runtime
Gradle
Slide 11
Slide 11 text
Your app’s code
JetBrains Runtime
Gradle
DCEVM
How does it work?
Slide 12
Slide 12 text
How does it work?
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent Recompiler
Slide 13
Slide 13 text
Gradle
Recompiler
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
How does it work?
Slide 14
Slide 14 text
Gradle
Recompiler
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
How does it work?
Slide 15
Slide 15 text
How does it work?
Gradle
Recompiler
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
DCEVM
Slide 16
Slide 16 text
How does it work?
Gradle
Recompiler
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
Slide 17
Slide 17 text
How does it work?
Gradle
Recompiler
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
Slide 18
Slide 18 text
How does it work?
Gradle
Recompiler
Dev
Tooling
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
Slide 19
Slide 19 text
How does it work?
Gradle
Recompiler
Dev
Tooling
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
Slide 20
Slide 20 text
How does it work?
Gradle
Recompiler
Dev
Tooling
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
Slide 21
Slide 21 text
How does it work?
Gradle
Recompiler
Dev
Tooling
Your app’s code
JetBrains Runtime
Gradle Hot Reload Agent
IDE
Slide 22
Slide 22 text
DCEVM
Dynamic Code Evolution Virtual Machine
class Offset(
val x: Int,
)
Current Class Loader
Slide 23
Slide 23 text
DCEVM
class Offset(
val x: Int,
val y: Int,
)
Dynamic Code Evolution Virtual Machine
Side Universe
Class Loader
class Offset(
val x: Int,
)
Current Class Loader
Slide 24
Slide 24 text
DCEVM
class Offset(
val x: Int,
val y: Int,
)
Dynamic Code Evolution Virtual Machine
Current Class Loader
Slide 25
Slide 25 text
What do you mean…
“migrate objects”?
Slide 26
Slide 26 text
DCEVM
Dynamic Code Evolution Virtual Machine
Offset@235235 Offset@534643 Offset@734122 Of
class Offset(
val x: Int,
)
Slide 27
Slide 27 text
DCEVM
Dynamic Code Evolution Virtual Machine
42
Header 13
Header 24
Header
Offset@235235 Offset@534643 Offset@734122 Of
class Offset(
val x: Int,
)
Slide 28
Slide 28 text
DCEVM
Dynamic Code Evolution Virtual Machine
42
Header 13
Header 24
Header
Offset@235235 Offset@534643 Offset@734122 Of
class Offset(
val x: Int,
val y: Int,
)
+
Slide 29
Slide 29 text
DCEVM
Dynamic Code Evolution Virtual Machine
42
Header 13
Header 24
Header
Offset@235235 Offset@534643 Offset@734122 Of
Offset@235235 Offset@534643 Offset@734
class Offset(
val x: Int,
val y: Int,
)
+
Slide 30
Slide 30 text
DCEVM
Dynamic Code Evolution Virtual Machine
42
Header 13
Header 24
Header
Offset@235235 Offset@534643 Offset@734122 Of
Offset@235235 Offset@534643 Offset@734
42
Header 13
Header Head
class Offset(
val x: Int,
val y: Int,
)
+
Slide 31
Slide 31 text
DCEVM
Dynamic Code Evolution Virtual Machine
42
Header 13
Header 24
Header
Offset@235235 Offset@534643 Offset@734122 Of
Offset@235235 Offset@534643 Offset@734
42
Header 13
Header Head
0 0
class Offset(
val x: Int,
val y: Int,
)
+
Slide 32
Slide 32 text
DCEVM
Dynamic Code Evolution Virtual Machine
Offset@235235 Offset@534643 Offset@734
42
Header 13
Header Head
0 0
class Offset(
val x: Int,
val y: Int,
)
+
Slide 33
Slide 33 text
Compose diffing
fun mediumPadding() = 16.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here's a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Slide 34
Slide 34 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here's a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 35
Slide 35 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here's a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 36
Slide 36 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here's a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 37
Slide 37 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here's a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 38
Slide 38 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here’s a counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 39
Slide 39 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here’s a wonderful counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Slide 40
Slide 40 text
fun mediumPadding() = 32.dp
@Composable
fun Counter() {
var counter by remember { mutableStateOf(0) }
Text("Here’s a wonderful counter:")
Card {
Button(
modifier = Modifier.padding(mediumPadding()),
onClick = { counter++ }
) {
Text("Clicked $counter times")
}
}
}
Compose diffing
Kotlin by JetBrains,
present and future
(office hours)
unsolved conf @ 12:00
Márton Braun
Sebastian Aigner
Slide 64
Slide 64 text
zsmb.co/talks
Márton Braun
@zsmb.co
Compose Hot Reload jb.gg/chr
KotlinConf app jb.gg/kc-app
Sebastian Sellmair’s content
KotlinConf talk jb.gg/kc25-chr
YouTube youtube.com/@s.sellmair
Blog blog.sellmair.io
Blazing Fast UI Development with