Literal Patching

This is hotter than hot reload.

When your edit only changes a literal value, HotSwan skips the entire incremental compilation step and patches the value directly on the running device. The result is visible in under 50 milliseconds from the moment you save the file.

This makes it practical to fine tune colors, spacing, font sizes, and text by eye, iterating as fast as you can type. Resource value changes in XML files (strings, colors, dimensions) are also patched through the same fast path. No build, no class swap, no recomposition delay.

What is literal patching

HotSwan maintains a secondary representation of every constant expression in your composable tree. When the plugin detects that a saved file differs only in constant values, it bypasses the entire build system and resolves the new values against the existing representation on device. The Compose runtime then reconciles the updated constants within the current frame boundary, so the change appears on the very next draw pass.

Because the build toolchain is never invoked, the entire round trip from keystroke to pixel is measured in tens of milliseconds rather than seconds.

What qualifies as a literal change

A literal change is any edit that only modifies constant values inside a composable function body. If the edit does not add, remove, or reorder any function calls or control flow, it qualifies for the fast path.

  • String literals: changing "Hello" to "Hello, World"
  • Integer and float literals: changing 16.dp to 24.dp, or 0.5f to 0.8f
  • Color hex values: changing Color(0xFF6C5CE7) to Color(0xFFFF5722)
  • Long and double literals: any numeric constant that the compiler treats as a fixed value

String template changes are also supported. If you change the fixed text portions of a template like "Total: $count items", the fixed fragments are patched while the dynamic parts remain unchanged.

How it works

Normal hot reload goes through the full build pipeline. Literal patching skips straight to the result.

Normal hot reload
Save File
Compile
Extract
Swap
Recompose
~1-3 seconds
Literal patching
Save File
Patch
Recompose
~50 milliseconds

When you save a file, HotSwan checks whether the change is limited to constant values. If it is, the build system is bypassed entirely. The new values are sent directly to the device and applied on the next frame. If the change involves anything beyond literals, the normal pipeline runs automatically.

Examples

Here are common editing patterns that trigger literal patching.

Change a color

Before
@Composable
fun ProfileCard() {
    val accent = Color(0xFF6C5CE7)
    Box(
        modifier = Modifier
            .background(accent)
    )
}
After
@Composable
fun ProfileCard() {
    val accent = Color(0xFFFF5722)
    Box(
        modifier = Modifier
            .background(accent)
    )
}

Adjust spacing and size

Before
Box(
    modifier = Modifier
        .padding(16.dp)
        .size(100.dp)
)
After
Box(
    modifier = Modifier
        .padding(24.dp)
        .size(150.dp)
)

Update text content

Before
Text(
    text = "Welcome back",
    fontSize = 18.sp,
)
After
Text(
    text = "Hello, World",
    fontSize = 24.sp,
)

Change a resource value

Editing existing values in strings.xml, colors.xml, or dimens.xml also triggers the fast path.

Before
<string name="greeting">Hello</string>
<color name="primary">#6C5CE7</color>
<dimen name="card_padding">16dp</dimen>
After
<string name="greeting">Welcome back</string>
<color name="primary">#FF5722</color>
<dimen name="card_padding">24dp</dimen>

One edit, many updates

When you store a literal in a local variable and reference it in multiple places, changing that single value updates every usage at once. For example, defining a color at the top of a composable and using it in three different modifiers means all three update on the same frame.

@Composable
fun Dashboard() {
    val accent = Color(0xFF6C5CE7)

    // All three pick up the new color instantly
    Box(modifier = Modifier.background(accent))
    Text(color = accent, text = "Status")
    Divider(color = accent)
}

Changing accent to a different hex value updates the background, text color, and divider in a single pass. This is useful for quickly iterating on a color palette or design system token without rebuilding.

When it falls back

Literal patching only applies when the edit is confined to constant values. If your edit also changes structure (adding a composable call, removing a parameter, changing control flow), HotSwan detects this and falls back to the normal hot reload path. The fallback is automatic and transparent.

A few specific cases that do not qualify for the fast path:

  • Adding or removing lines: If the line count of the function changes, the edit is not literal only.
  • Changing variable names or types: Renaming a variable or changing its type is a structural change.
  • Top level constants: Literals defined outside composable function bodies (such as const val or top level val) are not covered by the compiler plugin's wrapping. Move them inside the composable body if you want instant patching.

In all of these cases, HotSwan falls back to the normal hot reload path and applies the change as usual. The only difference is speed: literal patching completes in under 50 milliseconds, while the normal path takes a few seconds depending on your project size.