Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Blazing Fast UI Development with Compose Hot Re...

Blazing Fast UI Development with Compose Hot Reload (Android Budapest September 2025)

When working on UI, you want to see the results of your code changes as fast as possible. Waiting for apps to rebuild and relaunch, then getting the app to the desired state again only gets in your way.

Compose Hot Reload is a new JetBrains project that gives you live updates after code changes when running a Compose app on desktop - so you can see and feel how your app’s behaviour changes, without having to relaunch it at all. And you even get to keep your existing state!

In this talk, we’ll experience coding with Compose Hot Reload enabled with exciting live demos, and also learn a bit about how it all works under the hood.

If your project doesn’t have a desktop target yet… it might just be time to add one!

https://zsmb.co/appearances/android-budapest-september-2025/

Avatar for Márton Braun

Márton Braun

September 18, 2025
Tweet

More Decks by Márton Braun

Other Decks in Programming

Transcript

  1. Setup !// build.gradle.kts plugins { id("org.jetbrains.compose.hot-reload") version "1.0.0-beta07" } !//

    settings.gradle.kts plugins { id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0" }
  2. Setup !// build.gradle.kts plugins { id("org.jetbrains.compose.hot-reload") version "1.0.0-beta07" } !//

    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) }
  3. Setup !// build.gradle.kts plugins { id("org.jetbrains.compose.hot-reload") version "1.0.0-beta07" } !//

    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) }
  4. Setup !// build.gradle.kts plugins { id("org.jetbrains.compose.hot-reload") version "1.0.0-beta07" } !//

    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) }
  5. How does it work? Gradle Recompiler Dev Tooling Your app’s

    code JetBrains Runtime Gradle Hot Reload Agent
  6. How does it work? Gradle Recompiler Dev Tooling Your app’s

    code JetBrains Runtime Gradle Hot Reload Agent
  7. How does it work? Gradle Recompiler Dev Tooling Your app’s

    code JetBrains Runtime Gradle Hot Reload Agent
  8. How does it work? Gradle Recompiler Dev Tooling Your app’s

    code JetBrains Runtime Gradle Hot Reload Agent IDE
  9. 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
  10. DCEVM class Offset( val x: Int, val y: Int, )

    Dynamic Code Evolution Virtual Machine Current Class Loader
  11. DCEVM Dynamic Code Evolution Virtual Machine 42 Header 13 Header

    24 Header Offset@235235 Offset@534643 Offset@734122 Of class Offset( val x: Int, )
  12. 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, ) +
  13. 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, ) +
  14. 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, ) +
  15. 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, ) +
  16. 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, ) +
  17. 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") } } }
  18. 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
  19. 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
  20. 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
  21. 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
  22. 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
  23. 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
  24. 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
  25. 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