Skip to main content
Compose Hot Reload can be configured in multiple ways to suit your project’s needs. This page covers all the configuration options available in your Gradle build scripts.

Configuring the Main Class

The main class tells Compose Hot Reload which class contains your application’s entry point.

Priority Order

Compose Hot Reload uses the following precedence to determine the main class:
  1. Command-line argument: --mainClass
  2. Gradle property: -PmainClass=com.example.MainKt
  3. System property: -Dcompose.mainClass=com.example.MainKt
  4. Compose Multiplatform application.mainClass configuration
  5. Task-specific configuration in build script

In the Compose Desktop Application Block

If you’re using Compose Multiplatform, configure the main class in the application block:
build.gradle.kts
compose.desktop {
    application {
        mainClass = "com.example.MainKt"
    }
}
This configuration is automatically picked up by hot reload tasks.

In the ComposeHotRun Task

You can also configure the main class directly on hot reload tasks:
tasks.withType<ComposeHotRun>().configureEach {
    mainClass.set("com.example.MainKt")
}

Via Command Line

Override the main class at runtime:
./gradlew :app:hotRunJvm --mainClass com.example.MainKt

Configuring Run Tasks

You can customize the behavior of ComposeHotRun tasks:

Basic Configuration

build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    // Set the main class
    mainClass.set("com.example.MainKt")
    
    // Add JVM arguments
    jvmArgs = listOf(
        "-Xmx2G",
        "-XX:+UseG1GC"
    )
    
    // Set application arguments
    args("--verbose", "--config=dev")
}

Auto Reload Configuration

Enable automatic reload by default:
build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    isAutoReloadEnabled.set(true)
}
This can still be overridden from the command line with --no-auto.

Resource Directory Configuration

If you’re using Compose desktop resources, you may need to configure the resources directory:
build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    systemProperty(
        "compose.application.resources.dir",
        project.layout.buildDirectory.dir("compose/tmp/prepareAppResources").get()
    )
}
See Known Limitations for more details on this workaround.

Creating Custom Run Tasks

You can create custom run tasks for different configurations:
build.gradle.kts
tasks.register<ComposeHotRun>("runDev") {
    mainClass.set("com.example.MainKt")
    args("--environment=dev")
    systemProperty("app.debug", "true")
}

tasks.register<ComposeHotRun>("runProd") {
    mainClass.set("com.example.MainKt")
    args("--environment=prod")
    systemProperty("app.debug", "false")
}
Run them with:
./gradlew runDev --auto
./gradlew runProd

Configuring the JetBrains Runtime

Compose Hot Reload requires the JetBrains Runtime. You can configure how it’s obtained:

Automatic JBR Provisioning

Enable automatic JetBrains Runtime download and provisioning:
Automatic JBR provisioning is an experimental feature.
gradle.properties
compose.reload.jbr.autoProvisioningEnabled=true

Using Gradle Toolchains

Alternatively, use the Gradle toolchain resolver to automatically download JBR:
settings.gradle.kts
plugins {
    id("org.gradle.toolchains.foojay-resolver-convention") version "1.0.0"
}

Manual JBR Path

Specify a custom JBR installation:
gradle.properties
compose.reload.jetbrainsRuntime.binary=/path/to/jbr/bin/java

System Properties

Compose Hot Reload behavior can be controlled via system properties. You can set these in your build script or pass them at runtime.

In Build Script

build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    // Enable dev tools transparency
    systemProperty("compose.reload.devToolsTransparencyEnabled", "true")
    
    // Run dev tools in detached mode
    systemProperty("compose.reload.devToolsDetached", "true")
    
    // Disable reload effects
    systemProperty("compose.reload.reloadEffectsEnabled", "false")
}

Via Command Line

./gradlew hotRunJvm -Dcompose.reload.devToolsDetached=true

Available System Properties

Here are some commonly used system properties:
PropertyDescriptionDefault
compose.reload.devToolsEnabledEnable/disable dev tools windowtrue
compose.reload.devToolsDetachedRun dev tools as separate windowfalse
compose.reload.devToolsHeadlessRun dev tools without UIfalse
compose.reload.devToolsTransparencyEnabledEnable transparency effectstrue
compose.reload.reloadEffectsEnabledShow reload visual effectstrue
compose.reload.logLevelSet logging levelINFO
For a complete reference of all system properties, see the System Properties API Reference.

Gradle Properties

You can also configure hot reload using Gradle properties in your gradle.properties file:
gradle.properties
# JetBrains Runtime configuration
compose.reload.jbr.autoProvisioningEnabled=false
compose.reload.jetbrainsRuntime.version=21

# Build behavior
compose.reload.gradleBuildContinuous=false
compose.reload.gradleWarmupEnabled=true

# Main class (project-wide default)
mainClass=com.example.MainKt

Multi-Module Configuration

For projects with multiple modules, you can configure hot reload at the root level:
build.gradle.kts (root)
subprojects {
    plugins.withId("org.jetbrains.compose.hot-reload") {
        tasks.withType<ComposeHotRun>().configureEach {
            // Common configuration for all modules
            jvmArgs = listOf("-Xmx2G")
        }
    }
}
Or configure specific modules:
build.gradle.kts (root)
project(":app") {
    tasks.withType<ComposeHotRun>().configureEach {
        mainClass.set("com.example.app.MainKt")
    }
}

project(":samples") {
    tasks.withType<ComposeHotRun>().configureEach {
        mainClass.set("com.example.samples.SamplesKt")
    }
}

Environment-Specific Configuration

You can create environment-specific configurations using Gradle properties:
build.gradle.kts
val isDevelopment = project.findProperty("env") == "dev"

tasks.withType<ComposeHotRun>().configureEach {
    if (isDevelopment) {
        jvmArgs = listOf("-Xmx4G", "-XX:+UseG1GC")
        systemProperty("app.debug", "true")
        isAutoReloadEnabled.set(true)
    } else {
        jvmArgs = listOf("-Xmx2G")
        systemProperty("app.debug", "false")
        isAutoReloadEnabled.set(false)
    }
}
Run with:
./gradlew hotRunJvm -Penv=dev

Advanced Configuration

Statics Reinitialization Mode

Control how static variables are handled during hot reload:
build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    systemProperty(
        "compose.reload.staticsReinitializeMode",
        "CLEAR_ON_RELOAD"  // or "RETAIN"
    )
}

Virtual Method Resolution

Configure virtual method resolution for advanced hot reload scenarios:
build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    systemProperty("compose.reload.virtualMethodResolveEnabled", "true")
    systemProperty("compose.reload.dirtyResolveDepthLimit", "10")
}

Logging Configuration

build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    // Set log level
    systemProperty("compose.reload.logLevel", "DEBUG")  // TRACE, DEBUG, INFO, WARN, ERROR
    
    // Enable stdout logging
    systemProperty("compose.reload.logStdout", "true")
}

Configuration Examples

Example 1: Development Setup

build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    mainClass.set("com.example.MainKt")
    isAutoReloadEnabled.set(true)
    
    jvmArgs = listOf(
        "-Xmx4G",
        "-XX:+UseG1GC"
    )
    
    systemProperty("compose.reload.devToolsDetached", "false")
    systemProperty("compose.reload.reloadEffectsEnabled", "true")
    systemProperty("compose.reload.logLevel", "INFO")
}

Example 2: CI/Headless Environment

build.gradle.kts
tasks.withType<ComposeHotRun>().configureEach {
    mainClass.set("com.example.MainKt")
    
    // Disable UI components for headless environments
    systemProperty("compose.reload.devToolsEnabled", "false")
    systemProperty("compose.reload.reloadEffectsEnabled", "false")
    systemProperty("java.awt.headless", "true")
}

Example 3: Multiple Entry Points

build.gradle.kts
tasks.register<ComposeHotRun>("runMainApp") {
    mainClass.set("com.example.MainKt")
}

tasks.register<ComposeHotRun>("runAdmin") {
    mainClass.set("com.example.AdminKt")
}

tasks.register<ComposeHotRun>("runDebug") {
    mainClass.set("com.example.DebugKt")
    systemProperty("app.verbose", "true")
}

Next Steps

Build docs developers (and LLMs) love