Jetpack Compose latest release news lands with version 1.11.0, shipped through the Compose BOM 2026.04.01, and it is a bigger release than the point-version number suggests. Google published the announcement on April 22, 2026, and the official Jetpack Compose April '26 release notes lay out everything that shipped, from a default testing behavior change every team will hit immediately to a batch of experimental layout APIs aimed squarely at screen-level design. If you have been waiting to catch up on the Jetpack Compose latest release before touching your build.gradle, this is the practical rundown.
The headline story in this Jetpack Compose latest release is a split between "must deal with now" and "worth experimenting with." The v2 testing APIs becoming the default is not optional — it changes how your existing Compose tests execute. Trackpad input handling and preview wrappers are smaller but immediately useful. Grid, FlexBox, Styles, and MediaQuery are all marked experimental, previewing where two-dimensional, adaptive layout in Compose is headed next. Below is a complete tour of the top features in this release, migration notes on what actually breaks, gotchas, and a verdict on whether to upgrade now.
This is the change most teams will notice first, and it is the one most likely to break a green test suite overnight. Following the opt-in period introduced back in Compose 1.10, the v2 testing APIs are now the default in this Jetpack Compose latest release, and the v1 APIs are deprecated. The practical effect: the test coroutine dispatcher switches from something that ran launched coroutines eagerly to a StandardTestDispatcher, which queues coroutines instead of running them immediately.
That means a coroutine launched inside a composable under test — say, from a LaunchedEffect — no longer executes until you explicitly advance the virtual clock. Tests that quietly relied on eager execution will now see stale UI state until you call advanceUntilIdle() or step the scheduler yourself.
import androidx.compose.foundation.layout.Column
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.test.junit4.createComposeRule
import androidx.compose.ui.test.onNodeWithText
import kotlinx.coroutines.delay
import kotlinx.coroutines.test.runTest
import org.junit.Rule
import org.junit.Test
@Composable
fun WelcomeBanner() {
var message by remember { mutableStateOf("Loading...") }
LaunchedEffect(Unit) {
delay(100)
message = "Welcome back!"
}
Column { Text(message) }
}
class WelcomeBannerTest {
@get:Rule
val composeTestRule = createComposeRule()
@Test
fun bannerUpdatesAfterEffectRuns() = runTest {
composeTestRule.setContent { WelcomeBanner() }
// Old assumption: the LaunchedEffect had already run by this point.
// Under the v2 default StandardTestDispatcher, it has not.
composeTestRule.mainClock.advanceTimeBy(200)
composeTestRule.waitForIdle()
composeTestRule.onNodeWithText("Welcome back!").assertExists()
}
}
Google's own migration guide for the v2 testing APIs is the right first stop if your CI starts flaking after this Jetpack Compose latest release lands. The upside is real: StandardTestDispatcher mimics production timing far more closely than the old unconfined behavior, which means tests that pass now are less likely to hide genuine race conditions.
Trackpad handling gets a substantial overhaul in this Jetpack Compose latest release. Previously, trackpad events were funneled through the same pipeline as touch events, which caused a familiar annoyance: clicking and dragging on a trackpad could trigger scrolling instead of the expected drag gesture. Compose 1.11 now classifies trackpad pointer events as PointerType.Mouse instead of PointerType.Touch, and Modifier.scrollable and Modifier.transformable pick this up automatically — no code changes required for the common case.
On API 34 and above, trackpads also gain two-finger swipe and pinch gesture support, redundant touch slop is removed for trackpad pointers, drag-and-drop starts more intuitively, and text fields get double-click and triple-click word/line selection along with desktop-styled context menus. A new performTrackpadInput() testing API lets you validate all of this without a physical device.
import androidx.compose.foundation.gestures.scrollable
import androidx.compose.foundation.gestures.rememberScrollableState
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.input.pointer.PointerType
import androidx.compose.ui.input.pointer.pointerInput
@Composable
fun TrackpadAwarePanel() {
var offset by remember { mutableFloatStateOf(0f) }
var lastPointerType by remember { mutableFloatStateOf(0f) }
val scrollState = rememberScrollableState { delta ->
offset += delta
delta
}
Box(
modifier = Modifier
.fillMaxSize()
.scrollable(state = scrollState, orientation = androidx.compose.foundation.gestures.Orientation.Vertical)
.pointerInput(Unit) {
awaitPointerEventScope {
while (true) {
val event = awaitPointerEvent()
val pointer = event.changes.firstOrNull()
if (pointer != null && pointer.type == PointerType.Mouse) {
// Trackpad drags now arrive here instead of Touch,
// so a click-and-drag no longer fights with scrolling.
lastPointerType = 1f
}
}
}
}
)
}
For any app that gets meaningful ChromeOS or foldable-with-trackpad usage, this alone is worth the upgrade — it removes a class of bug reports that were previously nearly impossible to fix cleanly from application code.
Grid is one of the marquee experimental additions in this Jetpack Compose latest release. Row and Column handle linear arrangements well, but screen-level layouts — dashboards, settings panels, anything with cells that need to span multiple rows or columns — have always required hand-rolled Layout or ConstraintLayout code. Grid gives you a track-based API with gaps, cell spanning, and flexible "Fr" sizing units, purpose-built for that kind of structure rather than for scrollable lists.
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.gridItem
import androidx.compose.foundation.layout.Grid
import androidx.compose.foundation.layout.ExperimentalGridApi
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@OptIn(ExperimentalGridApi::class)
@Composable
fun AnalyticsDashboard() {
Grid(
modifier = Modifier.fillMaxSize(),
config = {
repeat(4) { column(0.25f) }
repeat(2) { row(0.5f) }
gap(16.dp)
}
) {
androidx.compose.foundation.layout.Box(
Modifier.gridItem(rowSpan = 2).background(Color(0xFF3F51B5))
)
androidx.compose.foundation.layout.Box(
Modifier.gridItem(columnSpan = 3).background(Color(0xFF009688))
)
androidx.compose.foundation.layout.Box(
Modifier.gridItem(columnSpan = 2).background(Color(0xFFFF7043))
)
androidx.compose.foundation.layout.Box(
Modifier.background(Color(0xFF9C27B0))
)
}
}
The design goal is explicit: Grid targets structural, screen-level architecture, while LazyVerticalGrid remains the right tool for scrollable, repeated-item collections. Treating those as two different problems, rather than stretching one API to cover both, is a welcome bit of API design discipline in this Jetpack Compose latest release.
Alongside Grid, FlexBox brings a CSS-flexbox-style container to Compose: an experimental API for wrapping, growing, and shrinking children across a main axis, with justifyContent, alignItems, and alignContent controls. It is the natural fit for tag lists, filter chips, and any row of variable-width content that should wrap instead of overflow or scroll.
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.FlexBox
import androidx.compose.foundation.layout.FlexWrap
import androidx.compose.foundation.layout.ExperimentalFlexBoxApi
import androidx.compose.foundation.layout.flex
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalFlexBoxApi::class)
@Composable
fun FilterChipRow(tags: List<String>) {
FlexBox(
config = {
wrap(FlexWrap.Wrap)
gap(8.dp)
}
) {
tags.forEach { tag ->
Text(
text = tag,
modifier = Modifier
.background(Color(0xFFE0E0E0))
.padding(horizontal = 12.dp, vertical = 6.dp)
.flex { grow(0f) }
)
}
}
}
Between Grid and FlexBox, this Jetpack Compose latest release gives you two purpose-built tools for the layout problems that previously forced either a rigid Row/Column tree or a drop down to a custom Layout composable.
Styles is the most conceptually different of the new experimental APIs in this Jetpack Compose latest release. Instead of composing modifiers and passing colors or shapes through parameters, a style block lets you describe a component's visual state — including interaction states like pressed — declaratively, with the framework handling the animated transition between states.
import androidx.compose.foundation.layout.ExperimentalStyleApi
import androidx.compose.material3.Button
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalStyleApi::class)
@Composable
fun GradientLoginButton(onClick: () -> Unit, modifier: Modifier = Modifier) {
Button(
onClick = onClick,
modifier = modifier,
style = {
background(Brush.linearGradient(listOf(Color(0xFF7B61FF), Color(0xFF3F8CFF))))
width(160.dp)
height(48.dp)
textAlign(TextAlign.Center)
externalPadding(16.dp)
pressed {
background(Brush.linearGradient(listOf(Color(0xFFFF4081), Color(0xFFE53935))))
}
}
) {
Text(text = "Log In")
}
}
Because styles are state-aware and animate automatically, a lot of the boilerplate around AnimatedContent or manual animateColorAsState calls for simple state-based visual changes disappears. It is still marked experimental, so treat it as a preview of direction rather than something to ship to production today.
MediaQuery is the other big experimental addition, and it targets a genuinely painful problem: reacting to window size, posture, input type, and other environment signals currently requires wiring together WindowInfoTracker, LocalConfiguration, and assorted device-specific checks. MediaQuery collapses that into a single declarative query.
import androidx.compose.foundation.layout.ExperimentalMediaQueryApi
import androidx.compose.foundation.layout.UiMediaScope
import androidx.compose.foundation.layout.mediaQuery
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.OptIn
@OptIn(ExperimentalMediaQueryApi::class)
@Composable
fun AdaptiveVideoPlayer() {
if (mediaQuery { windowPosture == UiMediaScope.Posture.Tabletop }) {
Text("Tabletop layout: controls below the fold, video on top")
} else if (mediaQuery { windowWidthClass == UiMediaScope.WidthClass.Expanded }) {
Text("Expanded layout: video and side panel side by side")
} else {
Text("Compact layout: video fills the screen")
}
}
For high-frequency signals, derivedMediaQuery() avoids unnecessary recomposition, and the API supports scope overrides so previews and tests can simulate device states without a physical foldable on hand. Between Grid, FlexBox, and MediaQuery, this Jetpack Compose latest release is clearly pointed at adaptive, large-screen, and foldable UI as a first-class concern rather than an afterthought.
A smaller but genuinely useful addition: the new PreviewWrapperProvider interface and @PreviewWrapper annotation let you inject shared logic — most commonly a theme — around every preview that opts in, instead of wrapping each @Preview composable in your theme manually every time.
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewWrapper
import androidx.compose.ui.tooling.preview.PreviewWrapperProvider
class AppThemeWrapper : PreviewWrapperProvider {
@Composable
override fun Wrap(content: @Composable () -> Unit) {
MaterialTheme {
content()
}
}
}
@PreviewWrapper(AppThemeWrapper::class)
@Preview
@Composable
private fun SubmitButtonPreview() {
Button(onClick = {}) {
Text(text = "Submit")
}
}
It is a small thing, but on a team with dozens of preview functions, removing one repeated wrapper call per preview adds up quickly, and it keeps theming consistent across the whole preview gallery in Android Studio.
Most existing Compose code compiles and runs unchanged, but a few things need attention before you roll this out broadly:
A handful of rough edges show up once teams start using this release in earnest:
Yes, upgrade the BOM soon — but budget real time for the testing migration before you do. The v2 testing APIs becoming default is the one part of this Jetpack Compose latest release that is not optional and not purely additive; it can turn a green CI pipeline red the first time you bump the BOM, so run your full test suite against 1.11 in a branch first and work through the StandardTestDispatcher timing fixes methodically.
Everything else here is close to a free upgrade. Trackpad handling and Preview Wrappers are pure quality-of-life wins with no downside. The deprecation of Modifier.onFirstVisible() and removal of the D-pad navigation flag are easy to grep for and fix in minutes. As for Grid, FlexBox, Styles, and MediaQuery — these are the interesting parts of this Jetpack Compose latest release to watch, but treat them as a preview of Compose's adaptive-layout future rather than something to build production screens on top of today. Prototype with them, file feedback through the linked issue trackers, and plan to revisit once they stabilize.
This closing example combines two of the release's experimental headline features — the Grid layout for screen-level structure and the Styles API for declarative, state-aware customization — into one self-contained composable:
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.ExperimentalGridApi
import androidx.compose.foundation.layout.ExperimentalStyleApi
import androidx.compose.foundation.layout.Grid
import androidx.compose.foundation.layout.gridItem
import androidx.compose.material3.Button
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
@OptIn(ExperimentalGridApi::class, ExperimentalStyleApi::class)
@Composable
fun ReleaseHighlightsScreen() {
MaterialTheme {
Grid(
config = {
repeat(2) { column(0.5f) }
repeat(2) { row(0.5f) }
gap(12.dp)
}
) {
StyledActionButton(
label = "Run Tests",
modifier = Modifier.gridItem(columnSpan = 2)
)
StyledActionButton(label = "View Grid Docs")
StyledActionButton(label = "View FlexBox Docs")
}
}
}
@OptIn(ExperimentalStyleApi::class)
@Composable
private fun StyledActionButton(label: String, modifier: Modifier = Modifier) {
Button(
onClick = {},
modifier = modifier,
style = {
background(Brush.linearGradient(listOf(Color(0xFF3F51B5), Color(0xFF009688))))
textAlign(TextAlign.Center)
externalPadding(12.dp)
pressed {
background(Brush.linearGradient(listOf(Color(0xFF303F9F), Color(0xFF00695C))))
}
}
) {
Text(text = label)
}
}
That is the shape of the Jetpack Compose latest release in one screen: a stable, structural layout tool paired with a declarative, animated way to style what sits inside it — a small taste of where Compose's adaptive UI story is headed next.