Dev Logs / 6 min read
Jetpack Compose August '26 Release: Mesh Gradients, Wide Color Gamut, and Grid Areas
A rundown of Compose 1.12, from the seat of someone building UI for Android TV and signage devices
Google just shipped the stable Jetpack Compose release for August 2026, bringing version 1.12 across the core Compose modules. As someone who spends most days building UI for Android TV and STB (set-top box) devices for digital signage, a few changes in this release hit close to home — especially the color handling and grid layout improvements that used to be a pain to hack together manually.
Before diving in, here's the BOM bump if you want to jump straight in:
implementation(platform("androidx.compose:compose-bom:2026.08.00"))
Breaking Changes First, So You're Not Caught Off Guard
Two things to watch before upgrading:
- compileSdk moves to API 37, which means a minimum AGP of 9.2.0 is required. Compose always tracks the latest compileSdk, so if your project is still on an older AGP version, update that first before bumping Compose.
Modifier.onFirstVisible()is now deprecated. The replacement isModifier.onVisibilityChanged(), which offers more precise visibility threshold tracking. If you're still using the old one for lazy-loading images or firing analytics when an item enters the screen, it's time to migrate.
Graphics: Mesh Gradients and Wider Color Support
This is the part that caught my attention the most. Compose 1.12 introduces MeshGradientPainter, letting you build multi-point gradients with more organic color transitions than a plain linear or radial gradient.
val gradientPainter = remember {
MeshGradientPainter(rows = 1, columns = 1) {
setVertex(0, 0, Offset(0f, 0f), Color.Red)
setVertex(0, 1, Offset(1f, 0f), Color.Blue)
setVertex(1, 0, Offset(0f, 1f), Color.Green)
setVertex(1, 1, Offset(1f, 1f), Color.Yellow)
}
}
Box(
modifier = Modifier
.aspectRatio(16 / 9f)
.fillMaxWidth()
.paint(gradientPainter)
)
If you've ever worked on signage content or splash screens that need a "living" visual feel without asking a designer to re-export assets every time the brand palette shifts, this API saves real time. Dynamic backgrounds that used to be faked with looping video or heavy bitmaps can now be replaced with a handful of vector-based lines of code.
Just as important: Compose 1.12 also brings full pipeline support for Wide Color Gamut (P3) and HDR rendering across graphics, paint, and shaders. Colors defined in non-sRGB spaces like Display P3 are now preserved all the way through to platform rendering instead of being clamped down to sRGB. That matters a lot if you're building for modern display hardware — TVs and monitors included. Worth noting: automatic sRGB fallback still kicks in when a color space isn't supported on a given Android version, or when the app runs on Android 9 (API 28) and below.
There's also a smaller but handy addition: LayerOutsets on GraphicsLayer and Modifier.graphicsLayer, which lets you extend a layer's visual bounds beyond its measured size — useful so shadows or glow effects don't get clipped once a layer is promoted to an offscreen buffer.
Styles API Is Still Experimental
The team first previewed the Styles API vision at Google I/O as a unified way to style components. This release confirms it's still in the foundational stage — locking down type safety and predictable behavior for custom design systems — so it remains experimental and open to breaking changes. Fine to poke at on a side project, but not something to lean on in production yet.
Runtime: Keyed SideEffect
SideEffect now accepts key arguments, so one-shot effects can re-fire whenever specific keys change — without reaching for LaunchedEffect or DisposableEffect when you don't actually need a coroutine or a dispose block.
@Composable
fun AnalyticsTracker(userId: String, screenName: String) {
SideEffect(key1 = userId, key2 = screenName) {
analytics.logScreenView(userId, screenName)
}
}
The claimed numbers: up to 90% faster than LaunchedEffect and about 20% faster than DisposableEffect. One thing worth watching if you migrate existing effects: SideEffect runs before DisposableEffect and LaunchedEffect, so the execution order changes — especially for LaunchedEffect blocks that were deliberately relying on running after the current frame completes.
Animation: Two-Stage Transitions for Predictive Back
DeferredTargetAnimation has graduated out of experimental, alongside two new composables: DeferredAnimatedContent and DeferredAnimatedVisibility. These enable two-stage transitions — think predictive back gesture tracking, where during the "deferred" phase animated properties like scale or offset can be manually driven by the user's swipe in real time. Once that deferred phase ends, the transition engine takes over with a seamless handoff, velocity transfer included, into the automatic transition. There's also a new permitTransformDuringDeferredTransition flag in SharedContentConfig controlling whether shared elements visually transform along with their parent containers during that deferred phase.
Text, Input, and Platform Integrations
Text fields got a solid batch of updates:
- Rich text formatting directly inside
BasicTextFieldvia a newaddStyle()method onTextFieldBuffer, supportingSpanStyleandParagraphStyle. Formatting now survives configuration changes. SelectionStategives programmatic control over text selection —selectAll(),clear(),select(TextRange),extendSelectionByWord()— plus a reactiveselectedTextslist to observe.- Credential Manager integration built right into text fields through the
credentialRequestsemantics property, so a login form can trigger a passkey or saved-credential prompt without extra plumbing. KeyboardTypenow includesDate,Time,DateTime, andSignedDecimal.BasicSecureTextFieldnow defaults toTextObfuscationMode.System.
Layout: Named Areas in Grid
For anyone building dashboard-style layouts or complex multi-region screens, the (still-experimental) Grid component now supports named areas — so you define regions semantically instead of juggling numeric row and column indices:
@OptIn(ExperimentalGridApi::class)
@Composable
fun DashboardLayout() {
Grid(
config = {
area("header", row = 0, column = 0, rowSpan = 1, columnSpan = 2)
area("sidebar", row = 1, column = 0)
area("content", row = 1, column = 1)
gap(16.dp)
}
) {
HeaderSection(modifier = Modifier.gridItem(areaId = "header"))
NavigationSidebar(modifier = Modifier.gridItem(areaId = "sidebar"))
MainContentView(modifier = Modifier.gridItem(areaId = "content"))
}
}
This is one I expect to reach for a lot on large-screen landscape layouts — TVs or multi-panel information boards — where the usual approach has been ConstraintLayout or a nest of Row/Column that turns fragile the moment the structure needs to change.
Performance and Testing
The team says this release focused on startup performance, with Time to Initial Display now comparable to Views in their internal benchmarks — good news for anything sensitive to boot time, including apps running on lower-spec hardware like Android boxes or STBs.
On the testing side, two new APIs are worth trying:
hasPendingWork()— passively checks whether the UI still has pending work without advancing the clock, ideal for manual animation loops.runWithoutImplicitWait()— temporarily disables implicit synchronization while stepping through frames manually, cutting redundant sync overhead when querying multiple nodes in one frame.
A few smaller wins too: captureToImage() can now capture a popup or dialog together with its anchor in one bitmap, and onRootWithViewInteraction makes it easier to test hybrid UI that mixes Compose with legacy Views like RecyclerView.
Wrapping Up
Compose 1.12 feels like a release that patches up a handful of old pain points while opening room for new experiments — mesh gradients and WCG for richer visuals, named Grid areas for complex layouts, and a stack of runtime and testing improvements that make daily development a bit smoother. If you work on anything touching non-standard displays like TVs or signage hardware, it's worth experimenting with WCG and Grid now, even while parts of it are still marked experimental.
Have you tried bumping to BOM 2026.08.00 yet? Which feature here is most relevant to what you're building? Drop a comment.
Originally published on Pilkupil Lab.