Wiring Android's MediaPipe LLM Inference API to a Streaming UI A developer published a pattern for streaming on-device LLM token output from MediaPipe's LLM Inference API into a Jetpack Compose Text component without dropped tokens or jank. The approach bridges MediaPipe's non-suspending callback into a Kotlin Flow via a bounded Channel with capacity 64 and BufferOverflow.SUSPEND, then batches emissions in an 80ms time window to cap recompositions at roughly 12 per second, keeping budget devices such as the Helio G88 within their frame budget at 25 tokens/sec. --- title: "Streaming LLM Tokens in Android with Jetpack Compose: Back-Pressure and the Frame Budget" published: true description: "Wire MediaPipe's LLM Inference API to Jetpack Compose using Kotlin Flow back-pressure, correct buffer sizing, and a 16ms recomposition budget that keeps mid-range devices jank-free at 20+ tokens/sec." tags: kotlin, android, mobile, architecture canonical url: https://mvpfactory.co/blog/streaming-llm-tokens-android-compose --- By the end of this tutorial you will have a production-ready pattern for streaming on-device LLM token output into a Compose Text component — without dropped tokens, without jank on mid-range hardware, and without the recomposition storm that trips up most first implementations. Here is the gotcha that will save you hours: MediaPipe does not give you a suspend function. It gives you a callback on a thread you do not own. The naive bridge will work fine on your Pixel 9 and silently drop frames on your users' Helio G88. MediaPipe exposes token output like this: inferenceSession.addQueryChunk prompt inferenceSession.generateAsync { partialResult, done - onToken partialResult, done } Two constraints that matter: Ignore these two constraints and you get frame drops that only appear under thermal throttling on mid-range hardware. That is exactly the device your users own. The cleanest bridge is a Channel with a bounded buffer. Here is the minimal setup to get this working: fun LlmInferenceSession.tokenFlow prompt: String : Flow