---
title: Window Breakpoints
description: Window breakpoint utilities for building adaptive Compose layouts.
---



```kotlin expandable title="BreakpointsDemo.kt" githubUrl="https://github.com/composablehorizons/compose-unstyled/blob/main/demo/src/commonMain/kotlin/com/composeunstyled/demo/breakpoints/BreakpointsDemo.kt"
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.widthIn
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.composables.uripainter.rememberUriPainter
import com.composeunstyled.CrossAxisAlignment
import com.composeunstyled.ProvideWindowWidthBreakpoints
import com.composeunstyled.Stack
import com.composeunstyled.StackOrientation
import com.composeunstyled.Text
import com.composeunstyled.WidthBreakpoint
import com.composeunstyled.WindowWidthBreakpoints
import com.composeunstyled.buildModifier
import com.composeunstyled.currentWindowWidthBreakpoint
import com.composeunstyled.demo.colors
import com.composeunstyled.demo.contentToken
import com.composeunstyled.demo.inputBackgroundToken
import com.composeunstyled.demo.mutedContentToken
import com.composeunstyled.demo.surfaceToken
import com.composeunstyled.theme.Theme

private val Compact = WidthBreakpoint("compact")
private val Medium = WidthBreakpoint("medium")
private val Expanded = WidthBreakpoint("expanded")

private val DemoWidthBreakpoints = WindowWidthBreakpoints {
  Compact startsAt 0.dp
  Medium startsAt 600.dp
  Expanded startsAt 840.dp
}

@Preview
@Composable
fun BreakpointsDemo() {
  ProvideWindowWidthBreakpoints(DemoWidthBreakpoints) {
    val widthBreakpoint = currentWindowWidthBreakpoint()
    val imagePainter = rememberUriPainter(
      "https://images.unsplash.com/photo-1500530855697-b586d89ba3ee" +
        "?auto=format&fit=crop&w=1200&q=80",
    )

    Box(
      modifier = Modifier.fillMaxSize(),
      contentAlignment = Alignment.Center,
    ) {
      Stack(
        modifier = Modifier
          .widthIn(max = if (widthBreakpoint isAtLeast Expanded) 860.dp else 360.dp)
          .background(Theme[colors][surfaceToken])
          .border(1.dp, Theme[colors][contentToken])
          .padding(14.dp),
        orientation = if (widthBreakpoint isAtLeast Expanded) {
          StackOrientation.Horizontal
        } else {
          StackOrientation.Vertical
        },
        crossAxisAlignment = CrossAxisAlignment.Start,
        spacing = 18.dp,
      ) {
        Image(
          painter = imagePainter,
          contentDescription = null,
          contentScale = ContentScale.Crop,
          modifier = Modifier
            .background(Theme[colors][inputBackgroundToken]) then buildModifier {
            if (widthBreakpoint isAtLeast Expanded) {
              add(Modifier.size(width = 320.dp, height = 280.dp))
            } else {
              add(Modifier.fillMaxWidth().height(280.dp))
            }
          },
        )

        Stack(
          modifier = Modifier then buildModifier {
            if (widthBreakpoint isAtLeast Expanded) {
              add(Modifier.weight(1f))
            } else {
              add(Modifier.fillMaxWidth())
            }
          },
          orientation = StackOrientation.Vertical,
          spacing = 12.dp,
        ) {
          Text(
            text = "Adaptive layouts",
            color = Theme[colors][contentToken],
            fontSize = 24.sp,
            lineHeight = 30.sp,
          )
          Text(
            text = "This card switches from vertical to horizontal at ${Expanded.name}",
            color = Theme[colors][mutedContentToken],
            fontSize = 15.sp,
            lineHeight = 22.sp,
          )
        }
      }
    }
  }
}
```



## Features

- Define custom width and/or height breakpoints.
- Build responsive layouts around named semantics instead of copy-pasting dimensions.
- Emit new state only when the resolved breakpoint changes, not on every window resize.

## Installation

```kotlin
implementation("com.composables:composeunstyled-breakpoints:2.10.0")
```

## Anatomy

```kotlin
val Compact = WidthBreakpoint("compact")
val Medium = WidthBreakpoint("medium")

val widthBreakpoints = WindowWidthBreakpoints {
  Compact startsAt 0.dp
  Medium startsAt 600.dp
}

ProvideWindowWidthBreakpoints(widthBreakpoints) {
  val widthBreakpoint = currentWindowWidthBreakpoint()
}
```

## Concepts

- `WidthBreakpoint`/`HeightBreakpoint` define a named breakpoint.
- `WindowWidthBreakpoints`/`WindowHeightBreakpoints` define the minimum window size where each breakpoint
  starts.
- Every breakpoint scale must include one breakpoint that starts at `0.dp`.
- `ProvideWindowWidthBreakpoints`/`ProvideWindowHeightBreakpoints` make one breakpoint scale available
  to their content scope.
- `ProvideWindowBreakpoints` makes both width and height breakpoint scales available to its content
  scope.
- `currentWindowWidthBreakpoint()`/`currentWindowHeightBreakpoint()` return a new resolved breakpoint
  only when the current window crosses into another breakpoint.

## Code Examples

### Building responsive layouts

Define the window widths your layout should respond to using `WindowWidthBreakpoints`.

Then use `ProvideWindowWidthBreakpoints` near the root of your app to make the current breakpoint available down the UI tree.

Use `currentWindowWidthBreakpoint()` to access the currently resolved breakpoint:

```kotlin expandable
val Compact = WidthBreakpoint("compact")
val Medium = WidthBreakpoint("medium")
val Expanded = WidthBreakpoint("expanded")

val widthBreakpoints = WindowWidthBreakpoints {
  Compact startsAt 0.dp
  Medium startsAt 600.dp
  Expanded startsAt 840.dp
}

ProvideWindowWidthBreakpoints(widthBreakpoints) {
  val widthBreakpoint = currentWindowWidthBreakpoint()
  val expanded = widthBreakpoint isAtLeast Expanded

  if (expanded) {
    BasicText("Expanded layout")
  } else {
    BasicText("Compact layout")
  }
}
```

### Using height breakpoints

Use `ProvideWindowHeightBreakpoints` with `currentWindowHeightBreakpoint()` when layout behavior
depends on available height:

```kotlin expandable
val Short = HeightBreakpoint("short")
val Tall = HeightBreakpoint("tall")

val heightBreakpoints = WindowHeightBreakpoints {
  Short startsAt 0.dp
  Tall startsAt 720.dp
}

ProvideWindowHeightBreakpoints(heightBreakpoints) {
  val heightBreakpoint = currentWindowHeightBreakpoint()
  val canShowDetails = heightBreakpoint isAtLeast Tall
}
```

## API Reference

### WidthBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `name` | `String` |  |
### HeightBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `name` | `String` |  |
### WindowWidthBreakpoints

| Parameter | Type | Description |
|-----------|------|-------------|
| `content` | `WindowWidthBreakpointsBuilder.() -> Unit` |  |
### WindowHeightBreakpoints

| Parameter | Type | Description |
|-----------|------|-------------|
| `content` | `WindowHeightBreakpointsBuilder.() -> Unit` |  |
### ResolvedWidthBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `value` | `WidthBreakpoint` |  |
| `name` | `String` |  |
### ResolvedHeightBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `value` | `HeightBreakpoint` |  |
| `name` | `String` |  |
### ProvideWindowBreakpoints

| Parameter | Type | Description |
|-----------|------|-------------|
| `width` | `WindowWidthBreakpoints` |  |
| `height` | `WindowHeightBreakpoints` |  |
| `content` | `() -> Unit` |  |
### ProvideWindowWidthBreakpoints

| Parameter | Type | Description |
|-----------|------|-------------|
| `breakpoints` | `WindowWidthBreakpoints` |  |
| `content` | `() -> Unit` |  |
### ProvideWindowHeightBreakpoints

| Parameter | Type | Description |
|-----------|------|-------------|
| `breakpoints` | `WindowHeightBreakpoints` |  |
| `content` | `() -> Unit` |  |
### currentWindowWidthBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `returns` | `ResolvedWidthBreakpoint` |  |
### currentWindowHeightBreakpoint

| Parameter | Type | Description |
|-----------|------|-------------|
| `returns` | `ResolvedHeightBreakpoint` |  |
