u/DistributionOk9460

▲ 1 r/ComposeMultiplatform+1 crossposts

An AI chat composer + A streaming-text typewriter

Spent a day on this weekend trying to build a ChatGPT-style streaming chat UI in a Compose Multiplatform as a side project and ran into a wall: the markdown rendering and streaming-token side of things on CMP is sparse.

The specific problem:

Rendering progressively-arriving markdown without flicker. If you have a Flow<String> of tokens from an LLM SDK and re-parse "Hello, **world" → "Hello, **wo" → "Hello, world!" as each token arrives, naive parsers will keep re-classifying the bold span and the text reflows constantly.

The fix is a prefix-stable parser: for any prefix of the input string, the same prefix of tokens must come out. That means treating an unclosed ** as plain text (not a half-rendered bold), and only flipping it to a Bold span when the closing ** arrives. Earlier tokens never re-classify.

I ended up writing this + a few other pieces (composer with slash commands and @ mentions,

send/stop state machine, syntax-highlighted code blocks that build up live) into two libraries:

Curious if anyone has tackled this differently — there's a streaming-markdown library in React (Vercel's streamdown) that takes a similar approach but I don't know of others in the JVM world.

Code:

val prompt = rememberPromptBarState()
val state = rememberStreamingTypewriterState()

// Send button auto-becomes Stop while the typewriter streams.
LaunchedEffect(state.isStreaming) {
    if (state.isStreaming) prompt.markStreaming() else prompt.markReady()
}

PromptBar(prompt, onSend = { vm.send() }, onStop = { state.stop(); vm.cancel() })
StreamingTypewriter(
    tokens = vm.responseFlow,
    state = state,
    renderer = rememberMarkdownTypewriterRenderer(),
)
u/DistributionOk9460 — 3 days ago
▲ 17 r/JetpackCompose+1 crossposts

Backdrop-blur library for Compose Multiplatform with an auto-tier that no-ops on low-RAM devices instead of OOMing. Looking for API feedback.

Hi all, I just open-sourced liquid-glass, a small Compose Multiplatform library for iOS 26-style frosted backdrop blur. Sharing here because the API design choice I made is the part I'd most like feedback on.

The problem: Compose's Modifier.blur blurs a composable's own content, not the backdrop. Chris Banes's haze library handles the backdrop-blur case cleanly. What I wanted on top of that was graceful degradation on memory-constrained devices, because the iOS 26 effect chews through GPU memory on a 2GB Android 11 device.

The approach: three explicit quality tiers, auto-picked per platform.

- Full on Android 12+ (non-low-RAM) and iOS 17+: 24dp blur, 1.4x saturation, full-res backdrop layer.

- Medium on iOS 15-16: 16dp blur, 0.5x downsampled backdrop.

- Fallback on Android < 12, isLowRamDevice, or iOS < 15: zero offscreen buffers, no blur, flat tint with edge sheen.

The Fallback tier allocates zero GraphicsLayers. The same code that draws frosted glass on a Pixel 9 quietly draws a tint on a 2GB device with no OOM, and no per-call-site branching.

API surface: rememberLiquidGlassState() + Modifier.liquidGlassSource() + Modifier.liquidGlass() / GlassCard / GlassButton / GlassNavBar.

What I'd like feedback on:

  1. Is the platform auto-detection sensible, or should the tier always be explicit at the call site?

  2. Are Full / Medium / Fallback the right names, or should they be capability-named (e.g., FullBlur / DownsampledBlur / FlatTint)?

  3. Anything obviously missing from the API for KMP backdrop-blur use cases?

Apache 2.0, on Maven Central as 0.1.0. Repo: https://github.com/NadeemIqbal/liquid-glass

u/DistributionOk9460 — 2 days ago
▲ 5 r/KotlinMultiplatform+1 crossposts

liquid-glass: iOS 26 frosted glass for Compose Multiplatform with a zero-alloc fallback for low-RAM Android

Hi everyone, sharing a new Compose Multiplatform library I open-sourced today.

liquid-glass adds iOS 26-style frosted backdrop surfaces to CMP. The API is Modifier.liquidGlass() plus three composables: GlassCard, GlassButton, GlassNavBar.

The bit I'm proudest of is the auto-tiered fallback. Three quality tiers picked per platform:

- Full on Android 12+ (non-low-RAM) and iOS 17+: 24dp blur, 1.4x saturation, full-res backdrop.

- Medium on iOS 15 to 16: 16dp blur, 0.5x downsampled backdrop.

- Fallback on Android < 12, isLowRamDevice, or iOS < 15: zero offscreen buffers, no blur, just a flat tint with edge sheen.

Fallback allocates zero GraphicsLayers, so the same code that draws frosted glass on a Pixel 9 quietly draws a flat tint on a 2GB Android 11 device. No OOM, no per-call-site branching.

Targets: Android, iOS (arm64 + simulator), Desktop (JVM), Wasm/JS. Apache 2.0, on Maven Central as 0.1.0.

Quick start:

```kotlin

val state = rememberLiquidGlassState()  // auto-picks tier for the device

Box(Modifier.fillMaxSize()) {

Image(

painter = painterResource(R.drawable.scenery),

contentDescription = null,

contentScale = ContentScale.Crop,

modifier = Modifier.fillMaxSize().liquidGlassSource(state),

)

GlassCard(

state = state,

modifier = Modifier.align(Alignment.Center).padding(24.dp),

) {

Text("Frosted, light-refracting surface")

}

}

```

Credit where it's due: Chris Banes's haze library solves backdrop-blur in Compose really well and is more mature than this. I built liquid-glass because I wanted the tiered fallback baked in by default, not as a thing each consumer has to wire up.

Limitations: 0.1.0. No GlassDialog or GlassBottomSheet wrappers yet, no Sk SL refraction shader, no dynamic-color edge sheen sampled from the backdrop. All on the roadmap.

Repo: https://github.com/NadeemIqbal/liquid-glass

Happy to answer questions about the per-platform auto-detection or the GraphicsLayer sampling approach.

u/DistributionOk9460 — 4 days ago