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:
Command-line argument: --mainClass
Gradle property: -PmainClass=com.example.MainKt
System property: -Dcompose.mainClass=com.example.MainKt
Compose Multiplatform application.mainClass configuration
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:
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:
All ComposeHotRun Tasks
Specific Task
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
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:
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:
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:
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
Command Line
compose.reload.jbr.autoProvisioningEnabled =true
./gradlew hotRunJvm -Pcompose.reload.jbr.autoProvisioningEnabled=true
Alternatively, use the Gradle toolchain resolver to automatically download JBR:
plugins {
id ( "org.gradle.toolchains.foojay-resolver-convention" ) version "1.0.0"
}
Manual JBR Path
Specify a custom JBR installation:
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
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:
Property Description Default compose.reload.devToolsEnabledEnable/disable dev tools window truecompose.reload.devToolsDetachedRun dev tools as separate window falsecompose.reload.devToolsHeadlessRun dev tools without UI falsecompose.reload.devToolsTransparencyEnabledEnable transparency effects truecompose.reload.reloadEffectsEnabledShow reload visual effects truecompose.reload.logLevelSet logging level INFO
Gradle Properties
You can also configure hot reload using Gradle properties in your gradle.properties file:
# 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:
subprojects {
plugins. withId ( "org.jetbrains.compose.hot-reload" ) {
tasks. withType < ComposeHotRun >(). configureEach {
// Common configuration for all modules
jvmArgs = listOf ( "-Xmx2G" )
}
}
}
Or configure specific modules:
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:
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:
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:
tasks. withType < ComposeHotRun >(). configureEach {
systemProperty ( "compose.reload.virtualMethodResolveEnabled" , "true" )
systemProperty ( "compose.reload.dirtyResolveDepthLimit" , "10" )
}
Logging Configuration
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
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
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
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